Unity Memory Management

Hi there,

I have a memory problem with my game. When I start the game it uses about 950-1050MB of memory (profiler AND taskmanager). The memory size increases over time. Now if I leave the App running over night, the next morning the Windows Taskmanager says my App uses 3GB of memory, the Unity Profiler however says I’d use only 1,1GB.

Unfortunately my game needs to run for at least 18h (because its used in a theme park). I’ve done multiple rounds of code optimization, trying to remove and delete references whenever possible - but nothing seems to do the trick. I call Application.LoadLevel several times a day (every hour or after every session), which reduces the memory by about 60MB.

Used Plugins (untouched):
I2 (Localization)
iTween
DebugLogger
Playmaker
SupersplinesPro

Modified Plugins:
RealisticCarControllerV2
SmartAI

Any input is appreciated.
Cheers
Lars

If memory increases while you aren’t doing anything that must men some background process is allocating new memory without releasing it.

You can check in hierarchy (in editor) if new game object are appearing constantly.
If that’s not the case it means you are holding references to variables that you aren’t using anymore. Try displaying the contents of your global variables to check for example if List<> elements keep growing.
If this doesn’t work you’ll have to go trough your code and disable parts of your code until you find the part that are allocating all that memory.

The app has an idle mode in which the app runs, just without the player (its a car simulation).
More importantly, I reload the Level every hour. I was under the impression, that if you call Application.LoadLevel does destroy every game object that is not static. When I tested that it turned out to be true. I had a static variable where I had the reference to a gameobject in. Once I call Application.LoadLevel the object is gone (cant remember the Exception, was no NullPointer though). While I do use a few static variables, every one of them get set on awake or start, which makes this the last point where I could possibly hold a reference to an object (destroyed or not). At this point (at least from my understanding) the GC must kick in and release the allocated memory. It does work to a degree (hence the 60MB drop) there still seems to be memory that the GC doesn’t release. I am not entirely sure where the problem lies, and I can’t debug properly because the Unity Profiler does not “see” that memory (which makes the profiler pretty useless for me). Why is there a difference anyway between the memory that unity says I allocated and what windows says im allocating?

When you load a level, Unity will call something like (or exactly?) Resources.UnloadUnusedAssets.
It will basically look for any stuff in memory that is not used and will unload it; this can free a large amount of memory.

There are other types of memory that may be “held” (or leaked), such as C# heap memory (allocating and holding object references) as one example.

Also, i’ve lately come across a new type of memory “leak” - in case you are creating textures and sprites at runtime, these are not freed by Unity when the object is destroyed. In that case, you have to manually destroy the texture object.

You can see the exact details of this issue in this thread: Texture leaks when loading scenes additively - Unity Engine - Unity Discussions

Last thing (maybe i should’ve started with this one ??) is to use the built-in profiler to diagnose where your memory allocations are made and what is causing the game to use such a large amount of memory.

Could you please explain what do you mean with that, liortal? Do you mean that, even doing “GameObject.Destroy ((Texture2D)myTexture);” is not enough?

All the best!

@jlupianez_freedom calling Destroy is enough. But you don’t normally destroy your textures when not using them anymore, are you?

Imagine the following code:

public static Texture2D CreateTexture(TextAsset image)
    {
        Texture2D tex = new Texture2D(1, 1, TextureFormat.RGB24, false);
        tex.wrapMode = TextureWrapMode.Clamp;

        tex.LoadImage(image.bytes);

        return tex;
    }

At runtime, this is used to construct a new Texture from an array of bytes.
When creating this texture at runtime and using it for a sprite, the memory will not be freed, even if the sprite itself is destroyed.

We encountered this since we load some scenes additively (on top of a main scene), and when destroying all of the additive scene’s sprites (by destroying the root object of the scene), these textures were not cleared.

Instead, i had to manually call Destroy on each and every Texture instance to make sure it was destroyed.