-Batchmode memory leak and fix

Hi guys, we had been struggling with a memory leak for some time and finally tracked it down.

We’re also using uLink but that’s not important.

When running a unity build without a camera and/or with -batchmode there is a pretty large memory leak when any SkinnedMeshRenderers are active in the scene… I wrote this little helper that I call on the server when an object is created that solves the issue but I hope it can be fixed internally to unity, here it is (c#) :

public static class ServerHelper
{
	public static void SetupForServer( GameObject obj )
	{
		Component[] renderers;
        renderers = obj.GetComponentsInChildren<Renderer>();
        foreach (Renderer rend in renderers) 
		{
            rend.enabled = false;
		}
	}
}

I just call ServerHelper.SetupForServer( RootOfMeshRenderer ); in an objects Awake method if Network.isServer and i know it has a skinned mesh renderer in its lower heirarchy

There may be a better way to do this like disabling it in the prefab and only enabling it on components etc, but it still shouldn’t leak, Hope this helps someone!

2 Likes

I can’t thank you enough for posting this. I was having the exact same problem, and boy would that have taken me a long time to figure out.

Hi Helk,

I think I have the same problem. In Amazon EC2 my game keeps using 4K more every couple of seconds. Is this what you experienced?

Helk I can’t THANK YOU enough!!! I was just wondering what on earth was going on… made the skinned meshed renderers on the server invisible and the memory leak stopped!!! THANK YOU SIR!!!
How did you figure it out?!

1 Like

Awesome Fix!

Now can the real fix get into F8?

This bug cost us a lot of work, I won’t elaborate but this was horrible and should be a easy fix, too bad I did not find this earlier!

Thanks for the share.

I’m not sure though how one can hit that leak as it would imply a much deeper problem in the games server code itself.
Its obviously a bug yes but actually that you even hit it means that your game does not do its job well on detecting batchmode right now at all. (System.Environment.CommandLine can be used here).

With that I mean that in batch mode, you either should have used server centric prefabs (preferable unless the warm up time of scenes etc does not matter for your game) or at least have your scripts destroy their ‘user experience’ components related to rendering, animation and audio as these take away some serious amount of cpu time that you want to spend on relevant things on the server normally instead of wasting the cpu cycles.

Actually I just had this issue with camera. However, my use case might be different.

Following character customisation example dressing room code, I instantiate renderer object into scene and point in game character mesh to renderer.sharedMesh. I purposely leave the renderer object in scene and the skinned renderer eats up memory through time.

Got this same issue in Unity 4.6 - A 4kb memory leak every few seconds, only when running in batchmode. The Unity profiler shows nothing - everything it profiles (except the overall Unity stat in the Simple profiler mode) remains exactly the same, with the leak being internal somewhere.

I’ve got any skinned mesh renderers (and most other renderes) disabled and it’s still happening. I’ll report back here if I track it down.

Batchmode seems to disable rendering automatically without renderers having to be manually disabled, since it uses a lot less memory and CPU even without any code changes (at least until the memory leak catches it back up!).

Removing all renderers has fixed the leak. Might have been the terrain? I’m not going to bother narrowing it down further because removing all renderers (and Terrain components since they’re a sort of renderer - obviously leave the Terrain Collider though) is a good enough solution for me.

Thank you very much Helk for posting the original solution to this. This would have been a nightmare to track down otherwise. Too bad this hasn’t been fixed in the engine in the intervening three years.

The real question now, is, what doesn’t leak in batch mode?

You have the right avatar for that comment lol

Hey guys,
thanks for your hints! Had the same problem.
I fixed it like this:

        Renderer[] rs = (Renderer[])FindObjectsOfType( typeof( Renderer ) );
        foreach( Renderer r in rs )
        {
            r.enabled = false;
        }
        SkinnedMeshRenderer[] smr = (SkinnedMeshRenderer[])FindObjectsOfType( typeof( SkinnedMeshRenderer ) );
        foreach( Renderer r in smr )
        {
            r.enabled = false;
        }
1 Like

It’s freaking insane that it’s been 3 years since that first post and this has not been fixed. How are you supposed to run a dedicated server?

1 Like