I’ve just found a nasty memory leak scenario in Unity. I’ve submitted a bug, bt I’m also posting this thread as a warning to fellow developers.
Here’s what happens: suppose you have a script that references some assets - prefabs, textures, whatever. This script is attached to an object in a scene. When this scene is unloaded, assets referenced by this object are unloaded too - provided, of course, that they’re not referenced somewhere else.
BUT if you store a reference to this object somewhere in code, then assets would NOT get unloaded! The object itself is destroyed on scene change, and you can’t access it from code - any attempt to use the reference causes an exception. However, with Resource.FindObjectsOfTypeAll() method you can enumerate all assets currently loaded, and these assets from now-destroyed object would still be there.
I’ve made a simple project to test this - it’s attached to the post. In it, there are three scenes. One is starting scene, and two others contain each an object that references a texture. The only difference is that “failScene” stores a reference to the object that in turn references the texture. When you return from this scene back to starting, and try to find the texture, it’d be there, and even displayed in OnGUI!
You’d have to build an actual project to test this, because in editor the texture seems to be loaded all the time right from the start. But when I checked with Windows .exe build, there was the memory leak: texture got unloaded after visiting “okScene”, but not after visiting “failScene”.
So be wary of storing references to objects after they are destroyed: it may seem harmless, but in fact causes memory leaks!
I’ve tested it all on 3.5.6. Don’t know if it happens on Unity4 beta, but I wouldn’t be surprised if it in fact does.
Submitted bug report number for anyone who is interested is an 492524