Mono heap size problem (debugging is hard, no SGen)

Hey all,

For a project at the University, I’m working with a team on a Unity game with high RAM usage. An external company has delivered us a lot of 3D data from the real world. This is data like the data in Google Streetview (as 3D triangle meshes + textures). This data is about ~100MB per 50x50m block, but could increase to ~200-300MB per block.

Seeing how this data is so large, we stream this data via a server. If the player leaves the neighbourhood, the block will be destroyed.

Here comes our problem: Mono keeps the giant heap (which can grow to 6GB) reserved, and does not defragment/compact the heap. The Unity profiler only shows us Unity RAM, which is not really a problem. The Mono RAM however, is not accessible in Unity.

We have multiple questions:

  1. Does anyone know if we can see/profile our Mono RAM somewhere?
  2. Seeing how Unity 5.2.0 uses Mono 2.0, an old garbage collector is used (sadly no SGen). Is there some way to use it or optimize our memory in another way?

If I didn’t provide enough info for you guys to answer our questions, I’m sorry! Feel free to ask more!

Thanks in advance.

Luuk-

Well, i guess you might have forgotten to actually destroy the mesh object unless you actually reuse it. Keep in mind that using the .mesh property will create a duplicate of the original mesh. The same thing happens with .material. If you want to completely destroy an object you have to destroy the mesh and material as well.

Also keep in mind that a lot built-in Unity classes are actually “managed proxy classes” for C++ objects. For example:

void FooBar()
{
    Mesh m = new Mesh();
}

calling “FooBar” will create a new Mesh object. The local variable m seems to be the only managed reference to that object and when FooBar finishes you might think that the mesh is up for garbage collection. However that’s not the case. Every class that is derived from UnityEngine.Object is a “tracked” object that has a native counterpart in the C++ world. See the class tree for a complete list (just find the “Object” class and see all the derived classes). Even you lost all references to an object you can simply ask Unity for the reference by using FindObjectsOfType. This method can find any UnityEngine.Object derived instance. Likewise all those objects can and have to be destroyed using the Destroy method.

When you call Resources.UnloadUnusedAssets, Unity will destroy all objects which aren’t currently in use. Our mesh object would be destroyed as well. UnloadUnusedAssets is implicitly called when you load a new scene. So objects that might have created materials, meshes, audioclips, textures, shaders, … usually don’t have to worry about cleaning up those objects when a scene change happens. However if you constantly creating new objects without cleaning up the hidden siblings, you just created a memory leak.