Search Unity

Does Unity always use double memory for texture in runtime?

Discussion in 'Editor & General Support' started by jjobby, Aug 31, 2013.

  1. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    161
    I tried creating three built exe on window.
    Scene 1. Plane with empty texture.
    Scene 2. Plane with 1024x1024 texture RGBA 32 bit 4 MB (from import setting).
    Scene 3. Plane with 2048x2048 texture RGBA 32 bit 16 MB (from import setting).

    I made sure that all textures didn't use mipmap and didn't read/write enable.

    Memory usage in task manager (I waited a bit until all scenes memory were stable)
    Scene 1. 29.9 MB
    Scene 2. 37.8 MB (different from Scene 1: 7.9 MB)
    Scene 3. 62.0 MB (different from Scene 1: 32.1 MB)

    It loos like that Unity allocated double memory for each texture. Is this an expected behavior?
     
  2. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Yes, that's what happens for me...but if I do use read/write enabled, the memory goes up by another 4MB for a 1024x1024 32bit texture, so I guess using double memory is better than using triple memory.

    --Eric
     
  3. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    161
    OK. That's good to know. I don't know what's the reason behind this behavior but is this a normal thing to do for Game Engine? I feel that it's a really waste of memory. My game has many textures for GUI which I can't compress them due to image quality. This behavior really makes it harder to manage memory for mobile.
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    It seems to me that it shouldn't happen, but I don't know what's going on behind the scenes exactly.

    --Eric
     
  5. meta87

    meta87

    Joined:
    Dec 31, 2012
    Posts:
    254
    Is this with static batching on or off? Because it doubles the memory usage if I'm not mistaken.
     
  6. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    161
    I hope that Unity developer read this thread and can shed some light for us. I really want to make sure if this behavior is an intentional or not. Can I directly pm them in the forum?

    No, it's just an empty scene with newly created plane. I didn't use any static in the scene.
     
    Last edited: Aug 31, 2013
  7. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Static batching isn't related to texture memory. The developers are probably all at Unite right now...if you know someone at Unite, get them to bug the developers in person. ;)

    --Eric
     
  8. meta87

    meta87

    Joined:
    Dec 31, 2012
    Posts:
    254
    Ahh I see, my bad :) Wish I was at Unite so I could pester Unity devs..
     
  9. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    161
    I don't know anyone at Unite. Sigh... In the meantime, I will try to contact support through Unity Bug Reporter.
     
  10. jjobby

    jjobby

    Joined:
    Nov 28, 2009
    Posts:
    161
    Is it normal that I don't get any confirmation email back from bug reporter? Or Unity bug report system doesn't have auto-reply email? I don't expect to receive immediately response but I want to make sure that my submission was successful. Should I send another one? :confused:
     
  11. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I always get an auto-confirmation mail from bug reports.

    --Eric
     
  12. Nidre

    Nidre

    Joined:
    Dec 12, 2012
    Posts:
    22
    Anyone found a solution for that ? or the reason of the problem ?
     
  13. Newcomma

    Newcomma

    Joined:
    Feb 10, 2015
    Posts:
    89
    bump, any news on this?
     
  14. Carpe-Denius

    Carpe-Denius

    Joined:
    May 17, 2013
    Posts:
    842
    Are those maybe just mipmaps?
     
  15. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    Just noticed this double memory usage and would like to know why it happens - and if it can be avoided.

    I create a new Texture2D from bytes.

    Size of new texture is 512x512 and format is RGB24.

    Memory used should be 1Mb (768Kb + 33% extra for mipmaps).

    In the editor the profiler tells me it's 2Mb, and it even worse on iOS device - 2.3Mb.
     
  16. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    495
    Yes,in profile memory is showing double...Anyone knows why?
     
  17. CandyTNT

    CandyTNT

    Joined:
    Feb 15, 2017
    Posts:
    1
    I get the same error in 5.4.3f1. I set maskNonReadable to true but nothing changed
     
  18. LeleUnity

    LeleUnity

    Joined:
    Jul 30, 2016
    Posts:
    97
    So what is the solution to this? I keep getting double of the size!! in no time I arrive to 100 mb of Ram used for the background!
     
  19. twhittaker

    twhittaker

    Joined:
    May 15, 2018
    Posts:
    10
    This is an older thread but I'm seeing the same thing. A 2048x2048 texture set to DX5 is reported in the inspector as 5MB which is correct. 2048*2048*1Bpp * ~1.33Mip = 5MB. However in the Profilers/Memory Profiler it's reported as 10MB. Texture does not have read/write enable. It almost appears that there is a system memory copy like DX9 managed textures. Is there any more information on this?
     
    LeleUnity likes this.
  20. Alex_Heizenrader

    Alex_Heizenrader

    Joined:
    May 16, 2019
    Posts:
    95
    Same here, our only change was loading a scene from a bundle instead of a prefab from a bundle. All texture memory shows double in the profiler and it must be true because it crashes on some devices it didn't use to (low ram devices).

    Any ideas?
     
  21. eatbuckshot

    eatbuckshot

    Joined:
    Jan 10, 2016
    Posts:
    24
    On unity 2019.4.0f1, I too noticed this phenomenon where the profiler would list a runtime created texture under
    Scene Memory
    with a size double than that in the texture preview in the inspector.

    I've stumbled upon a way to actually reduce the memory usage by the texture2d such that it is no longer double the normal size of the texture. It involves using a coroutine to wait one frame after destroying the previous texture in a material before assigning a newly created texture... For some reason if it is destroyed and it is immediately set to a new texture it will cause it to use double the memory.

    However, what is interesting is, if I were to call
    compress()
    on the texture, even without having waited a frame, it won't use the extra memory. It seems the compression method triggers some kind of freeing of the previously destroyed texture. On android, since the compress method is not supported, it will show up as double the memory if there hasn't been a one frame wait in a coroutine after deleting a texture.

    Edit: it seems.. having the yield return null immediately after instantiating the new texture works too... even though the destroy for the other texture is the line after
    Code (CSharp):
    1.  
    2. IEnumerator loadtexture2()
    3.     {
    4.         Texture2D texmain = (Texture2D)GetComponent<Renderer>().sharedMaterial.mainTexture;
    5.         Texture2D tex = new Texture2D(texmain.width, texmain.height,texmain.format,false);//, texmain.format,true);
    6.         //Texture2D tex = new Texture2D(w, h, TextureFormat.ARGB32, false);//, texmain.format,true);
    7.  
    8.         Destroy(otherquad.sharedMaterial.mainTexture);
    9.         yield return null; //For some reason it is necessary to wait 1 frame for the previous texture memory to be freed
    10.         if (otherquad.sharedMaterial.name != "Unlit/Texture")
    11.         {
    12.             otherquad.sharedMaterial = new Material(Shader.Find("Unlit/Texture"));
    13.         }
    14.         otherquad.sharedMaterial.mainTexture = tex;
    15.  
    16.         tex.name = ">RightTex";
    17.  
    18.         //NativeArray<Byte> texmainbytes = texmain.GetRawTextureData<Byte>().GetSubArray(0,texmain.width*texmain.height*4);
    19.         NativeArray<Byte> texbytes = tex.GetRawTextureData<Byte>();
    20.         int length = texbytes.Length;
    21.  
    22.         //texbytes.CopyFrom(texmainbytes);
    23.         tex.SetPixels32(texmain.GetPixels32(0)); //This is more agnostic way to copy but possibly slower
    24.  
    25.         tex.Apply(false);
    26.         //tex.Compress(false);
    27.  
    28. }
    In this example I had a 1024x1024 texture, which at ARGB32, should be 4 bytes per pixel, or 4 Megabytes total, however it was showing 8 Megabytes in the profiler. This could be observed with calling GetRuntimeMemorySizeLong(tex) as well.

    Do note, I'm under the impression that if mipmaps are enabled it might end up using up to double the memory anyway since the extra mip levels are probably going to be stored such that the whole texture is still a power of two.

    It seems this also may plague DownloadHandlerTexture.GetContent() when downloading images to turn into a texture after calling UnityWebRequestTexture.GetTexture(url)

    also some related info here:
    https://forum.unity.com/threads/destroying-textures-materials-created-with-new.656680/
     
    Last edited: Jun 19, 2020