Understanding the managed heap is essential for memory management in Unity. For more information on profiling managed memory and how to optimize memory, see the understanding managed memory section of the Understanding Optimization in Unity guide.
Assets cause native memory and managed memory implication during runtime. The Unity runtime doesn't return managed memory to the operating system for reuse until the user terminates the application. The managed heap grows if it becomes too fragmented and runs out of available memory. Due to this unpredictable behavior, it is critical to know how Assets occupy managed memory:
Use Destroy(myObject) to destroy an Object and release its memory. Setting a reference to a Object to null does not destroy it.
You should set persistent (long-term) objects as classes and ephemeral (short-term) objects as structs. Structs are not allocated on the heap and thus not garbage collected.
Reuse temporary work buffers to keep temporary garbage low, instead of allocating frequently.
An Enumerator does not clean up its memory until it exits.
You should avoid never-ending Coroutines, especially when allocating large amounts of managed memory within on, as Coroutines hold onto stack allocations on the heap until the Coroutine ends.