Author Topic: Memory Leak in UI Atlas combined with UI Sprite  (Read 3378 times)

TRC Support

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 2
    • View Profile
Memory Leak in UI Atlas combined with UI Sprite
« on: October 15, 2013, 08:17:57 AM »
We are encountering a problem due to an apparent memory leak in the NGUI system – some UI Atlases remain in memory even though the objects which reference them were destroyed. Below there is a description of how the problem can be replicated.

We have two prefabs with the following structure:
   -> UIPanel
        -> UISprite

We are then creating an instance of each prefab and parent them under the “Camera” game object of the UI Root.  We are keeping a reference to these instances so that when the script is destroyed we also destroy them.

We are then loading a completely blank scene, wait for it to load, and then unload the unused assets using:
   yield return Application.LoadLevelAsync(“BLANKSCENE”);
   yield return Resources.UnloadUnusedAssets();

After waiting for the unused assets to be unloaded, the memory profiler still shows that the atlas used by the prefabs is still in memory (the prefabs are using the same atlas).

We have noticed that if we only create a single instance of the prefabs, then the atlas is properly unloaded – but if we create both, then the atlas remains in memory.

The atlas will remain in memory even if the resources are unloaded again afterwards using Resources.UnloadUnusedAssets().
 
We do not know why the atlas remains in memory because the scripts and game objects which were referencing it have been destroyed and an empty scene was loaded. The memory profiler indicates that the atlas is still used by its material.
 
What are we doing wrong?

TRC Support

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 2
    • View Profile
Re: Memory Leak in UI Atlas combined with UI Sprite
« Reply #1 on: October 16, 2013, 06:26:46 AM »
We have found the source of the memory leak - The Remove() and RemoveAt() methods of the BetterList implementation are not setting the last element of the buffer to default(T).

This is the fix that we have done in BetterList:
  1. for (int b = i; b < size; ++b) buffer[b] = buffer[b + 1];
  2. // The line that fixed the issue:
  3. buffer[size] = default(T);
  4. return true;
  5.  
« Last Edit: October 16, 2013, 06:35:01 AM by TRC Support »

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Memory Leak in UI Atlas combined with UI Sprite
« Reply #2 on: October 16, 2013, 01:13:32 PM »
Thanks for looking into it, I will add your fix to the main repo.