How to get useful information from memory leak log?

Hi! I get this kind of memory leak warning time to time. But I don’t know where exactly it is pointing to. Because non of the file mentioned in the log was created by me (Sometimes it did point out a mistake in my own code, but sometime it didn’t). How do I fix the memory leak like the one below?

Found 8 leak(s) from callstack:
0x00007ffb9d2a5a60 (fab96c2570f706e77c11dff4f327b4c) 5e153e87cf3392ad54330b6ac62b9919
0x000002164d75d8b5 (Mono JIT Code) (wrapper managed-to-native) object:wrapper_native_0000021650042AC0 (intptr,intptr)
0x000002164d7c8d8b (Mono JIT Code) Unity.Entities.SystemBaseRegistry:ForwardToManaged (intptr,Unity.Entities.SystemState*,void*) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/SystemBaseRegistry.cs:365)
0x000002164d7c8c33 (Mono JIT Code) Unity.Entities.SystemBaseRegistry:CallForwardingFunction (Unity.Entities.SystemState*,Unity.Entities.UnmanagedSystemFunctionType) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/SystemBaseRegistry.cs:336)
0x000002164d7c8ceb (Mono JIT Code) Unity.Entities.SystemBaseRegistry:CallOnCreate (Unity.Entities.SystemState*) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/SystemBaseRegistry.cs:371)
0x000002164d7c856b (Mono JIT Code) Unity.Entities.WorldUnmanagedImpl:CallSystemOnCreateWithCleanup (Unity.Entities.SystemState*) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/WorldUnmanaged.cs:615)
0x000002164d789dab (Mono JIT Code) Unity.Entities.World:GetOrCreateSystemsAndLogException (Unity.Collections.NativeList`1<Unity.Entities.SystemTypeIndex>,int,Unity.Collections.AllocatorManager/AllocatorHandle) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/World.cs:1282)
0x000002164d7887c3 (Mono JIT Code) Unity.Entities.World:GetOrCreateSystemsAndLogException (Unity.Collections.NativeList`1<Unity.Entities.SystemTypeIndex>,Unity.Collections.AllocatorManager/AllocatorHandle) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/World.cs:1321)
0x000002164d786e53 (Mono JIT Code) Unity.Entities.DefaultWorldInitialization:AddSystemToRootLevelSystemGroupsInternal<Unity.Entities.DefaultWorldInitialization/DefaultRootGroups> (Unity.Entities.World,Unity.Collections.NativeList`1<Unity.Entities.SystemTypeIndex>,Unity.Entities.ComponentSystemGroup,Unity.Entities.DefaultWorldInitialization/DefaultRootGroups) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/DefaultWorldInitialization.cs:253)
0x000002164d76e723 (Mono JIT Code) Unity.Entities.DefaultWorldInitialization:AddSystemToRootLevelSystemGroupsInternal (Unity.Entities.World,Unity.Collections.NativeList`1<Unity.Entities.SystemTypeIndex>) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/DefaultWorldInitialization.cs:292)
0x0000021645cd7c13 (Mono JIT Code) Unity.Entities.DefaultWorldInitialization:Initialize (string,bool) (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities/DefaultWorldInitialization.cs:145)
0x00000216eef3ffb3 (Mono JIT Code) Unity.Entities.AutomaticWorldBootstrap:Initialize () (at ./Library/PackageCache/com.unity.entities@1.2.1/Unity.Entities.Hybrid/Injection/AutomaticWorldBootstrap.cs:17)
0x00000215acdfc8d5 (Mono JIT Code) (wrapper runtime-invoke) object:runtime_invoke_void (object,intptr,intptr,intptr)
0x00007ffb11b84bfe (mono-2.0-bdwgc) mono_jit_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/mini/mini-runtime.c:3445)
0x00007ffb11abd254 (mono-2.0-bdwgc) do_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3068)
0x00007ffb11abd3cc (mono-2.0-bdwgc) mono_runtime_invoke (at C:/build/output/Unity-Technologies/mono/mono/metadata/object.c:3115)
0x00007ff64a7830c4 (Unity) scripting_method_invoke
0x00007ff64a760e34 (Unity) ScriptingInvocation::Invoke
0x00007ff64a3e889c (Unity) RuntimeInitializeOnLoadManager::ExecuteInitializeOnLoad

Hi there, here are a couple of notes:

What I do to debug leaks in the editor:

  • run your editor with the -log-memory-performance-stats argument. That’ll give you more context on the leaks
  • set the Leak Detection Level in the Preferences>Jobs to Enabled with Stack Trace

Debugging:

  • if you get a reliable stack trace, go to that part of the code and make sure you are disposing the allocators you used - native containers, entityqueries, etc.
  • make sure that you’re using the correct allocators based on their lifetimes. I’ve had instances where I don’t complete jobs and just wait for the dependency to complete on its own, and used UniTask, which meant some allocators I used in a job actually need to be alive for more than 4 frames, so they need to be Persistent instead.
  • here’s a thread about leaks when creating queries
  • do you have GetOrCreateSystem calls when things are being destroyed or cleaned up? This may happen in parts of GameObject code that uses Jobs for hybrid purposes, and accidentally still run OnDisable or OnDestroy

Aside from those, I ignore the ones I can’t fix on my end. Although, most of the errors I had similar to yours only happen in the editor and not in builds, even with the log argument above or development builds. Might be a different case.

Hope it helps!

[edit] added more info [/edit]

1 Like

Thank you for your detailed answer, Neil! I will follow your instruction to tackle those memory leaking.
I have a few questions:

1 Did you mean entering -log-memory-performance-stats at the right “…” → Add Command Line Arguments in the Unity Hub? And is there a documentation for this, because this is totally new to me. I searched it here Unity - Manual: Unity Editor command line arguments (unity3d.com) but couldn’t find the command you mentioned.

2 I thought all jobs are promised to be completed in 4 frames if I don’t manually call jobHandle.Complete. But as you said, some lives longer than 4 frames. So in what scenario will we use TempJob? why don’t we just use either Temp (for those you will dispose in the same frame) or Persistent (for other cases).

Hi there! You’re welcome.

  • Yes. You can add that argument via Unity Hub, or if you’re launching your project via a bat file. This argument is in the Standalone Player Arguments. You can also find other arguments here. If you’re in the editor, you can also go to Preferences>Diagnostics then set some values there. But, keep in mind that this can easily break the editor. If that happens, launch with this argument --reset-diagnostic-switches
  • Not sure where it’s promised that jobs complete in 4 frames. That sounds familiar though. I have jobs for streaming a game world that are longer than 4 frames ( more info here , I don’t use Complete() and instead waited for Unity to do its thing and just ran an async method). To determine which allocator to use, think of the data you’re using in the jobs and when you need the results of the job itself. If you want to go beyond that, think about performance too, because the different allocators have varying performance for allocating and disposing of their allocated memory. Unity’s documentation has a good benchmark to get you started. This blog is also a good read, and if you like graphs ;).
  • There are also some cases that if a job or the application itself is interrupted and the job is not finished properly, you can introduce memory leaks. For example, exiting play mode while a job is running. In that case, might be a good idea to create finalizers/destructors to manually release any memory. This doesn’t look clean, but I’m not sure if there are other ways to dispose these. I’m open to suggestions.

Here’s a screenshot of Unity warning you that there may be leaks and to enable further logging to get a stacktrace. The letter A is the allocation that needs a proper trace.

[edit] added more info [/edit]

1 Like

Thank you a lot, Neil! There’s a bunch a things and learning material that are new to me. Thank you again!

1 Like