Memory Leaks

I am posting this again because I got no response.

Currently, I have a simple project that simply has a few GUITextures that get swapped in and out. I’m loading the associated Textures dynamically from the Resources directory. Under Instruments I’m seeing leaks for memory allocated at the following stack traces, for example.

So my question is, are these something that would be caused by my code or are they engine bugs? Is there a way I can avoid this?

 0 libSystem.B.dylib malloc
 1 libstdc++.6.dylib operator new(unsigned long)
 2 UnityGame std::_Rb_tree<ShaderLab::FastPropertyName, std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty>, std::_Select1st<std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> >, std::less<ShaderLab::FastPropertyName>, std::allocator<std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> > >::_M_create_node(std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> const)
 3 UnityGame std::_Rb_tree<ShaderLab::FastPropertyName, std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty>, std::_Select1st<std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> >, std::less<ShaderLab::FastPropertyName>, std::allocator<std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> const)
 4 UnityGame std::_Rb_tree<ShaderLab::FastPropertyName, std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty>, std::_Select1st<std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> >, std::less<ShaderLab::FastPropertyName>, std::allocator<std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> > >::insert_unique(std::pair<ShaderLab::FastPropertyName const, ShaderLab::PropertySheet::TexEnvProperty> const)
 5 UnityGame ShaderLab::PropertySheet::PropertySheet(ShaderLab::PropertySheet const)
 6 UnityGame ShaderLab::IntShader::MakeProperties() const
 7 UnityGame Shader::MakeProperties() const
 8 UnityGame GUITexture::BuildSheet()
 9 UnityGame GUITexture_SetTexture(Reference<GUITexture>, Reference<Texture>)
10 UnityGame .Lm_68f
0 libSystem.B.dylib malloc
1 libstdc++.6.dylib operator new(unsigned long)
2 UnityGame ShaderLab::IntShader::MakeProperties() const
3 UnityGame Shader::MakeProperties() const
4 UnityGame GUITexture::BuildSheet()
5 UnityGame GUITexture_SetTexture(Reference<GUITexture>, Reference<Texture>)
6 UnityGame .Lm_68f
0 libSystem.B.dylib malloc
1 libstdc++.6.dylib operator new(unsigned long)
2 UnityGame ShaderLab::PropertySheet::PropertySheet(ShaderLab::PropertySheet const)
3 UnityGame ShaderLab::IntShader::MakeProperties() const
4 UnityGame Shader::MakeProperties() const
5 UnityGame GUITexture::BuildSheet()
6 UnityGame GUITexture_SetTexture(Reference<GUITexture>, Reference<Texture>)
7 UnityGame .Lm_68f

Also, here’s the extracted code that I’m basically using to create the GUITextures. This has been simplified, but these are the order of operations that happen.

Originally I was just destroying the gameObject and assuming the texture would be destroyed as well. I added an explicit texture destroy step to see if it helped, and it didn’t.

GameObject gameObject = new GameObject(name);
Texture texture = Instantiate(Resources.Load(path));
		
// Don't stretch me unless I ask for it
gameObject.transform.localScale = Vector3.zero;
		
GUITexture guiTexture = (GUITexture)gameObject.AddComponent(typeof(GUITexture));
guiTexture.texture = texture;
guiTexture.pixelInset = textureRect;

......

// Later on
Destroy(texture);
texture = null;

gameObject.guiTexture.texture = null;
Destroy(gameObject.guiTexture);

Destroy(gameObject);

Add some debug code to monitor the number of Texture instances. See http://www.unifycommunity.com/wiki/index.php?title=DetectLeaks for some example code. If the texture count is going up you’re creating, but not deleting, some texture somewhere (I wouldn’t finger an engine leak, but it’s always a possibility).

Just because you destroy something or set its value to null, doesn’t mean it is destroyed in memory, not until the garbage collector collects the objects. You can try to GC.Collect after you destroy your objects in the code to force a garbage collection, but watch out if you have objects with a limited lifespan, they could get collected also.

Yes, currently there is a leak with dynamically created GUITextures. Will be fixed in next Unity version.

It seems to me that a couple of steps are out of order. This:

// Later on 
Destroy(texture); 
texture = null; 

gameObject.guiTexture.texture = null; 
Destroy(gameObject.guiTexture);

should be this instead, no?

// Later on 
Destroy(texture); 
texture = null; 

Destroy(gameObject.guiTexture); 
gameObject.guiTexture.texture = null;

Ouch. Could you define “dynamically created” for us? Does this mean we’ll leak memory as long as we create and assign GUITextures in code instead of through the GUI?