Symptoms
I am destroying a GameObject and calling Resources.UnloadUnusedAssets() to unload Assets but I can see that the Assets remain in memory.
Cause
UI events hold strong references to objects. This means they will prevent the object they reference from being garbage collected.
For example, if you have a GameObject with the following script (which holds a reference to a Texture):
using UnityEngine; public class MyScript : MonoBehaviour { public Texture2D texture; public void Foo() { } }
And you have a button that uses an on-click event to trigger a function in MyScript (as shown below), you must then destroy the GameObject using GameObject.Destroy(gameObject) and call Resources.UnloadUnusedAssets.
If you check the Memory Profiler you will see that, after calling Resources.UnloadUnusedAssets, the Texture remains in memory. This is because the UI event holds a reference to the script and prevents the Texture from being released.
Resolution
A simple solution to this problem is to set the reference to null in a DestroySelf function that can be called to destroy the GameObject as shown below:
void DestroySelf() { texture = null; // remove the reference GameObject.Destroy(gameObject); }
Then, after calling Resources.UnloadUnusedAssets, the Texture should be released.
More Information
You may find the following documentation helpful:
- Documentation on Resources.UnloadUnusedAssets
- Documentation on Resources.UnloadAsset
- Documentation on EventTrigger
- Documentation on Event System
Additionally, you may also find the below tutorials useful: