Resources.UnloadUnusedAssets vs. GC.Collect

Right now in my game i have set up my UI as prefabs that i user Resources.Load() on and instance as i need them.

when the user is no longer using that UI i would like to release those resources back.
Can i simply call GC.Collect() in the destroy of my script for my UI?
should i call Resources.UnloadUnusedAssets() in the destroy of my script for my UI?
should i do both?

any suggestions would be greatly appreciated.

These are not the same thing.

GC.Collect instructs the Mono garbage collector to perform a collection. This will look for objects and will clean up those that have nothing referencing them (note that this is a Mono feature that knows nothing about the existence of Unity. The objects that are collected are Mono heap objects, and not Unity game objects).

Resources.UnloadUnusedAssets is Unity’s API for looking up any unneeded Unity objects that are currently loaded, and unload them to free up memory. Maybe this calls GC.Collect internally, who knows.

This is run automatically by Unity when loading new scenes. Not sure about the case where you dynamically load and destroy objects from Resources… (but it’s always good to profile and see the results).

2 Likes

Do both. :smile:
From my experience it is important to call Resources.UnloadUnusedAssets() . Only calling GC.Collect() for example will not destroy a Texture2D even if it is no longer referenced.

2 Likes

liortal’s guess is correct, Resources.UnloadUnusedAssets is indeed calling GC.Collect inside. So if you already calling Resources.UnloadUnusedAssets, you shouldn’t call GC.Collect

17 Likes

Thank you very much everyone.

1 Like

I have a loading screen, and I don’t want to it be unloaded when loading a new scene, so I can switch back to loading screen very fast when needed. Is this possible?

Maybe you can use DontDestroyOnLoad on your object like:

    private void Awake()
    {
        if (_instance == null)
        {
            _instance = Instance;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject); // prevent duplicates
        }

    }

…or check THIS out.