Skip to content

Zuntatos/UnityHeapDump

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 

Repository files navigation

UnityHeapDump

Tool to dump memory to text files for inspection

Primary use is to find which static fields hold how much memory in order to find possible object leaks. For leaking of unity objects, please use the detailed memory profiler included in Unity3D. Total tracked memory found by this script can be much higher than the heap size, as an object with shared ownership will be counted towards every owner.

Use the menu item "Tools/Memory/Dump Heap" or call UnityHeapDump.Create() somewhere from your code to create a memory dump at %projectroot%/dump/. The process may take several seconds (or a lot more), depending on heap size and complexity.

Tool was developed for lack of a method to inspect the heap or create a dump using Unity3D, as:

  • The builtin profiler only tracks objects inheriting from UnityEngine.Object
  • Can't seem to use the 3rd party memory dump tools from visual studio or monodevelop with unity
  • Can't seem to use the profiling functionality of mono, as one can't pass the required arguments (would require mono rebuild/hack)
  • The experimental Memory Profiler from Unity3D only works with IL2CPP (and standalone IL2CPP is not available yet)

Output format

Example of a small class with 3 static fields:

Static (Players): 720 bytes
    loadedPlayers (System.Collections.Generic.Dictionary`2[NetworkID,Players+Player]) : 588
        valueSlots (Players+Player[]:12) : 184
            0 (Players+Player) : 56
        keySlots (NetworkID[]:12) : 132
        linkSlots (System.Collections.Generic.Link[]:12) : 120
        table (System.Int32[]:12) : 72
    connectedPlayers (System.Collections.Generic.List 1[Players+Player]) : 104
        _items (Players+Player[]:4) : 72
    PlayerHasID (System.Func 3[Players+Player,NetworkID,System.Boolean]) : 24

Example of a small assembly summary (this example is not a sensible usecase I guess, but it's small so:)

Assembly: System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e of total size: 13684
    Type: System.Security.Cryptography.AesTransform of size 9092
    Type: Consts of size 4528
    Type: System.Linq.Expressions.ExpressionPrinter of size 32
    Type: System.Linq.Expressions.Expression of size 24
    Type: System.TimeZoneInfo of size 4
    Type: System.Threading.ReaderWriterLockSlim of size 4

A summary of the results is available at %projectroot%/dump/log.txt. This contains all Types and Components parsed and Errors at the end. The summary lists Types in order of size, by order of total Assembly size.

  • Unity3D code Assemblies are printed to a file in the form of %projectroot%/dump/statics/%assembly%/%size%-%type%.
  • Other Assemblies are printed to a file at %projectroot%/dump/statics/misc/%size%-%type%.
  • Unity object results are printed to %projectroot%/dump/uobjects/%size%-%type%
  • Unity scriptableObject results to %projectroot%/dump/sobjects/%size%-%type%

Every file starts with the Types total summed size or all static references (or instance in case of unity objects).

  • A 'normal' reference is printed in the following format: %fieldName% (%type%) : %totalSize%.
  • An Array is printed like: %fieldName% (%type%:%arraySize%) : %totalSize%. An array item has its index as %fieldName%.

Indented afterwards are all object fields associated with the instance. Value type fields are not listed individually, but their size is included in the parent. Unless the value type is a struct with references to objects; those are listed.

Settings

Not much, but there are 3 constants in the main file; TYPE_MIN_SIZE_TO_PRINT, minimum byte count required before the type is printed to log.txt ROOT_MIN_SIZE, minimum byte count to create a file for the type CHILD_MIN_SIZE, minimum byte count to print the reference itself inside of the file (this is the main variable to tweak for scaling output size)

Issues

Not all memory is properly traversed. Known missing regions:

  • Static fields of generic class instances, only static fields on found instances will be found
  • Proper traversing of [System.ThreadStatic] fields.
  • References on the stack

Memory use will be biased because ALL the static constructors will be run, whether or not they were referenced before.

Various Types throw errors due to having bad implementations for GetHashCode() or Equals (Object). Parsing of the root Type causing the error is currently stopped, and parsing of the next Type is started. (This may actually be the cause for the missing size)

Credits

Idea/code was vaguely inspired by https://github.com/Cotoff/UnityHeapEx , but that code took multiple minutes to dump and created a 500 MiB .xml file for my use case, which was not really usable.

About

Tool to dump memory to text files for inspection

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages