I found some fairly old questions related to this on both the forums and UnityAnswers. However, I can’t find any clear info from the Unity documentation. So, I thought I’d ask for some clarification here.
I have a Component that’s used frequently on my UI objects. On Awake, it creates a material and a texture to send to the material.
material = new Material(shader);
texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
// Add data to texture here...
material.SetTexture(_Tex, texture);
Because I manually created this material and this texture, do I also need to manually call Destroy on these assets when the Component is destroyed to avoid a memory leak? If so, is properly destroying these assets as simple as:
private void OnDestroy()
{
if(texture != null)
{
Destroy(texture);
texture = null;
}
if(material != null)
{
Destroy(material);
material = null;
}
}
Do I need to worry about calling Resources.UnloadAsset or something else? Are the null checks necessary before destroying? Is it necessary to null the variable references?
It’s a bit unclear to me what needs to be manually cleaned up vs. what is automatically taken care of due to garbage collection or internal Unity housekeeping.
1 Like
If I remember correctly, Materials, Textures and Meshes need to be destroyed manually, aka will not be cleaned up via garbage collection. I think that may be it.
And you don’t need to do anything else after that! Just destroy em’ and that’s good. No need to make them null or check if they’re null or unload the assets. 
Josh is right. Just went through this myself. If you are reusing texture variable I would just do
material = new Material(shader);
if(texture != null) Destroy(texture);
texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
// Add data to texture here...
material.SetTexture(_Tex, texture);
1 Like
Just to clarify for anyone else struggling with this: Anything inheriting from UnityEngine.Object created by user code will create managed and native memory resources and needs to be Destroyed manually.
5 Likes
I know this is quite old post, but there is something want to be sure about it, when I destroy it manually and then reuse it, Does it uses the same memory address?
Bec I’m trying to minimize the Managed memory fragments and I want the compiler to reuse the same address to allocate the new texture not use different one. bec on 32bit version, I found that unity struggle to free memory sections compared to 64bit and thus app is leaking from memory sections whenever it try to allocate new objects that are not fit in free blocks in available sections and thus it expand with new sections again until it crash.
I can make a new post about this issue if the behavior is not as it should
Once it is destroyed, you can’t reuse it. The native part is gone at the end of frame and the managed parts gets GC collected whenever nothing references it anymore. Once it is collected, there’s a very tiny chance that a newly created object will get the same address, but that requires A) a GC collect between destroy+nulling and recreation, B) is unlikely and C) while it might avoid some little bit of fragmentation, a droplet of water on a hot stone.
There’s something about 32 bit fragmentaing faster than 64 bit that we are roughly aware of but that might be better for a new thread and maybe a bug report. I’m not sure if it is a bug yet, but we have fuzzy info on it so it might help.
1 Like