Is this a memory leak or what?

Hi,

since we are currently getting “Fatal error in gc Too many heap sections” on our game in Webplayer (Internet Explorer) we are searching for possible leaks or sections with lots of allocations.

I just tried some things out and found a possible leak with materials. So please correct me if I’m doing any error in this code:

using UnityEngine;
using System.Collections;

public class MemLeak : MonoBehaviour
{
	public Shader m_shader;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
	
		for(int i = 0;i < 10000;i++)
		{
			Material m = new Material(m_shader);
			Material.Destroy(m);
		}
		
	}
}

This keeps adding memory to the instance. So it’s a leak.
This code works fine:

using UnityEngine;
using System.Collections;

public class NoMemLeak : MonoBehaviour
{

	// Use this for initialization
	void Start ()
	{
	
	}
	
	// Update is called once per frame
	void Update ()
	{
		for(int i = 0;i<10;i++)
		{
			Texture2D t = new Texture2D(2048,2048);
			Texture2D.Destroy(t);
		}
	}
}

Any suggestions why this happens? I just wanted to clear out what you guys think about it before posting a bug in the engine.

Destroy doesn’t remove anything from memory, until such time as you load a new level or use Application.UnloadUnusedAssets.

–Eric

Can’t you just use the regular UnityEngine.Destroy ? I think it works fine. I don’t see why destroy wouldn’t remove from memory, this would make no sense?

There’s no such thing as UnityEngine.Destroy. Destroy is a static method implemented on UnityEngine.Object. Since everything in UnityEngine derives from UnityEngine.Object then it’s valid regardless.

Oh sorry, I thought it was directly from UnityEngine. I just use the regular Destroy ( without Material. in front of it ). I have a simple script from the wiki indicating how many GameObjects and Materials etc are loaded, and these decrease when I use the Destroy?

My only point was that methods have to be implemented in some kind of object. UnityEngine is just the namespace of the API.

I think I remember hearing somewhere that the specific overrides of Destroy expect the type that they are implemented in. So Object.Destroy expects an Object, GameObject.Destroy expects a GameObject etc etc. I’m not sure of the specific benefits so someone with more experience would have to speak to that.

Destroy doesn’t remove objects from memory. This is why you need something like Resources.RemoveUnusedAssets which will walk the game hierarchy to determine whether or not an object is reference anymore. It seems that Unity holds references to objects derived from UnityEngine.Object even when they are removed from the game which is why normal Garbage Collection will never pick them up.

Hi,

thanks for your replies. I know that Destroy does not remove anything from memory. However one would expect the amount of memory not to rise constantly until unity runs out of memory when the objects are not longer referenced. I posted this as a bug due to advice from the beta users mailing list.

Given the code you posted I actually would expect that. Every frame you create 1000 Materials that are not removed from memory. What really needs to happen is for the documentation surrounding Destroy to be made better so it’s clear what is actually happening.