Author Topic: NGUI crashes at large atlases  (Read 9853 times)

betonos

  • Guest
NGUI crashes at large atlases
« on: July 24, 2012, 08:39:54 AM »
Hi,

I'm having problem of the NGUI crashing when working with large atlases. What I'm doing is changing properties of series of atlases. I set padding, then select one of textures within atlas, then make it re-generate the atlas by clicking add/update. What I get at one point is:

DynamicHeapAllocator out of memory - Could not get memory for large allocationCould not allocate memory: System out of memory!
Trying to allocate: 8388612B with 32 alignment. MemoryLabel: Texture
Allocation happend at: Line:345 in /Applications/buildAgent/work/d9c061b1c154f5ae/Runtime/Graphics/Texture2D.cpp
Memory overview


[ ALLOC_TEMP_THREAD ] used: 32752B | peak: 0B | reserved: 262144B

[ ALLOC_DEFAULT ] used: 106606866B | peak: 411944658B | reserved: 268435456B

[ ALLOC_GFX ] used: 1052225466B | peak: 1111413203B | reserved: 1059411326B
Size           |  Num Used|  Num Free|
      8-15     |         0|         2|
     16-31     |         0|        11|
     32-63     |        39|        10|
     64-127    |       113|         5|
    128-255    |        77|         9|
    256-511    |       132|         1|
    512-1023   |       321|         6|
   1024-2047   |       282|         9|
   2048-4095   |        42|         5|
   4096-8191   |        67|         4|
   8192-16383  |        52|         6|
  16384-32767  |        60|         1|
  32768-65535  |        24|         0|
  65536-131071 |        47|         1|
 131072-262143 |        29|         0|
 262144-524287 |        55|         0|
 524288-1048575|        20|         1|
1048576-2097151|         8|         1|
2097152-4194303|         6|         0|
4194304-8388607|         9|         0|
8388608-16777215|         1|         0|
16777216-33554431|         2|         0|
33554432-67108863|         3|         0|

Label          |   Allocated|       Count|Largest Alloc
VertexData     |      201326|         110|       58152|
Geometry       |        2640|          55|          48|
Texture        |  1052021500|        1237|    89478488|
*Total*        |  1052225466|        1402|         N/A

One of the atlases is 4096x4096. When changed alone, it usually works (but not always!). But when changed in series one-by-one, it almost always crashes. Changing the atlas to 2048x2048 (for example by slicing the assets by half) helps, so it seems this is a memory problem indeed. This is a bit strange, as my system has 12 GB of ram. However, I suspect Unity gets only 4 GB or something (being 32 bit) and there we go having problems.

When debugging, I've located the error to happen at AssetDatabase.ImportAsset method. The call stack display gives the following:

UIAtlasMaker->AddOrUpdate->ExtractSprites->NGUIEditorTools.ImportTexture->ImportTexture->MakeTextureAnAtlas->ImportAsset

- BTW, NGUI is calling this method twice during each single atlas add/update operation, which seems pretty non-optimized.

Any help would be appreciated. I can't use smaller atlases, I can't use less atlases. I need the code to work OK under those conditions and it doesn't.

PhilipC

  • Guest
Re: NGUI crashes at large atlases
« Reply #1 on: July 24, 2012, 09:35:39 AM »
So if i'm understanding this correctly (just need to be 100% sure before i go digging) you are changing the padding on one atlas then you proceed to change the padding on another atlas right after correct?

Also just for clarity are you using Unity's packing method or the new method? (was added 2 versions ago so if you dont see the checkbox "Unity packer" your just using Unity's)

betonos

  • Guest
Re: NGUI crashes at large atlases
« Reply #2 on: July 24, 2012, 09:50:56 AM »
I'll update to the latest version ASAP. I've been using Unity packer.

Here is the little code I've written to hunt down the bug (and with this code I am able to reproduce the bug 100%). It seems the fault is on Unity memory management side.

foreach (GameObject gameObject in objectList) // this list contains all assets from project, I'm acquiring them elsewhere
      {
         UIAtlas atlas = gameObject.GetComponent<UIAtlas>();
         if (atlas)
         {   
            UISettings.atlas = atlas;
            UISettings.atlasPadding = 2;
            
            // now, a bad hack is done: a texture must be added to atlas so that it changes the padding...
            
            HashSet<string> spriteNames = new HashSet<string>();
            
            spriteNames.Add(atlas.GetListOfSprites()[0]); // retrieve first sprite
            spriteNames = FileNamesToPaths(spriteNames); // get the path
            Texture2D tex = AssetDatabase.LoadAssetAtPath(spriteNames.ElementAt(0), typeof(Texture2D)) as Texture2D;
               
            UIAtlasMaker.AddOrUpdate(atlas, tex);
            
            EditorUtility.SetDirty(gameObject);

         }
      }

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: NGUI crashes at large atlases
« Reply #3 on: July 24, 2012, 05:06:03 PM »
Yup, looks like something in Unity. As far as I can tell, there is no way to unload an asset, so refreshing is done by re-importing the texture and calling the asset database refresh. Even without working with the atlas maker tool Unity's memory keeps growing as I work on games, forcing me to restart it roughly every 12 hours.

betonos

  • Guest
Re: NGUI crashes at large atlases
« Reply #4 on: July 26, 2012, 09:21:58 AM »
Ok, I'm almost sure it's due to Unity / Mono memory management. The trick is, when you load too many assets and for some reason they are not released from memory by GC you end up eating the whole memory and Unity crashes. Currently I can't even load the project properly on fresh seat because the assets can not import in one batch due to memory! And the new iPad requires HUGE textures.

And you can't free the mem in any way, Object.DestroyImmediate doesn't seem to work...

Too bad Unity doesn't even plan to make Unity 64-bit in version 4.x :(

Any idea how to browse through large collection of assets without problems?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: NGUI crashes at large atlases
« Reply #5 on: July 26, 2012, 04:17:01 PM »
My suggestion? Stop using textures. iPad3 is designed for vector graphics -- geometry and/or vertex-colored stuff. Not textures.

taishsoft

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 12
    • View Profile
Re: NGUI crashes at large atlases
« Reply #6 on: July 31, 2012, 04:11:22 AM »
Yup, looks like something in Unity. As far as I can tell, there is no way to unload an asset, so refreshing is done by re-importing the texture and calling the asset database refresh. Even without working with the atlas maker tool Unity's memory keeps growing as I work on games, forcing me to restart it roughly every 12 hours.
Resources.UnloadUnusedAssets() is not the way?

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: NGUI crashes at large atlases
« Reply #7 on: July 31, 2012, 04:12:07 AM »
Nope. That only works at run-time from what I've seen.