[Check the original post at Unity Memory Management: Unload That Asset!]
I have a question for you regarding Unity memory management; when exactly is Unity releasing the memory your game assets are taking?
Most game developers wrongly assume it's released when you stop using them (whatever using means).
But... This assumption is wrong.
Let's find out why.
In this post, I'll share with you:
How most game developers (wrongly) assume their game assets are unloaded as soon as they stop using them
The negative consequences of assuming so
When exactly your assets are unloaded if you're NOT using addressables
And if you do use addressables: when are your addressable assets truly unloaded?
There's a reason this topic is relevant.
Here's what I see in most profiles: an increasing amount of used RAM and a confused developer asking me why.
"That must be wrong, I'm destroying my game object instances", they tell me.
And here's what I usually answer: "sorry, destroying instances won't necessarily get your memory back".
If you're aware of this fact, this issue will rarely be a concern.
But if you're not, then you might run into confusion and/or trouble.
Let's see why.
Quick Navigation (redirects to new tab)​
Unity Memory Management: Asset Unloading Assumptions
Consequences of Wrong Assumptions
Traditional Memory Management: Releasing Memory
Addressables Memory Management: Releasing Memory
The Switch to Addressables — The Guru's Way
Unity Memory Management: Asset Unloading Assumptions
Here's a typical case:
You load a scene.
You spawn a few enemies from a prefab.
Your player kills them and then you destroy all these instances. You even go as far as to remove the original reference to the prefab to make sure it's removed from memory.
The player keeps playing. However, the memory taken by that prefab didn't come back and your internal dialog says "shitty editor".
Here's another:
You additively load a scene that contains the pause menu UI. All its sprites are loaded, and that's fine.
The user returns to the game and you unload that additive scene.
You profile again and aren't happy to see the sprites are still in memory.
And the last one: you call Addressables.Release(myInstance) on an addressable asset. You're furious to see that nothing changed in your memory layout.
"What the f*** is going on here?", you curse aloud.
These all are examples of wrong assumptions most game developers make regarding Unity memory management and asset unloading.
And these assumptions might have somewhat nasty consequences.
Consequences of Wrong Assumptions
If you believe memory is released when it is NOT, then you might run into trouble at some point.
You'll think you have more free memory than you actually have.
→ This won't endanger your game often, as a good operating system will kindly remind Unity to clean its shit when it becomes too greedy. But some OS won't be that forgiving when it comes to memory (Oculus Quest comes to mind).
However, your mental sanity is at risk.
If you ever played Arkham Horror, or Eldritch Horror for the matter, you'll know better than to play with sanity points.
→ Here's the second problem: profiling your game won't be accurate anymore because the numbers you see won't match what you expect.
This will lead to questions such as "where are these extra 200MB coming from?" or "why is this still in memory even if I destroyed all references to it?". Even worse, you could end up asking yourself why are you in gamedev after all.
Okay, calm down.
We want both our gameplay and our profiling experiences to be silk smooth, right?
We don't want to hear the iron-like fist of our boss striking your desk asking about those kickstarter users complaining about crashes.
All good. I'll help you understand when exactly Unity unloads your assets and how to help it do it sooner.
I'll split the explanation in two sections:
When are your assets unloaded if you're NOT using addressables — i.e. using the traditional Unity memory management
When addressables will unload your assets if you do use it
Traditional Memory Management: Releasing Memory
Basically, Unity wants it safe for the game developers. And so it adds protection.
Unity is over-protective of memory and therefore under-performing.
I don't say this is wrong, as this saves you from taking aspirin. But they could be more transparent with memory management so everybody is aware of what's going.
If you're not using addressables but the traditional memory management flow, Unity follows a specific memory release pattern: Unity releases your assets' memory during the cleaning process and only if your asset meets the cleaning requirements.
This is when the memory cleaning process takes place: