As you develop and iterate in the Unity Editor, Unity automatically loads and reloads your project code as necessary to incorporate changes you make. This process is referred to as code reload. Code reload involves the following key phases:
By default Unity automatically reloads code as part of an Asset Database refresh, when it detects changes to your scripts or other assets.
If you choose to, you can also configure the Editor to reload code on transition between Edit mode and Play mode.
The Editor loads assemblies into several instances of AssemblyLoadContext (Microsoft). An AssemblyLoadContext is a .NET mechanism that groups a set of assemblies so that they load and unload together. The Editor puts code with different lifetimes into separate contexts:
Because each context loads and unloads as a unit, a code reload unloads only the contexts that need to change, which is usually just the one that holds your code. The long-lived contexts keep their code and data in memory, so the Editor doesn’t need to load them again, and reloads finish faster.
Unloading a context is cooperative rather than forced. The Editor asks the runtime to unload the context, and the garbage collector releases it only when nothing outside the context still uses it. A context can unload only when both of the following conditions are true:
GCHandle.If either condition isn’t met, the old context stays in memory next to the new one that replaces it. This is a code reload leak.
Code in the long-lived contexts stays loaded across reloads, so any reference that it holds to your code also survives the reload. Most leaks come from a reference of this kind, or from background work that’s still running when the reload starts. For more information about the .NET unloading requirements, refer to How to use and debug assembly unloadability in .NET (Microsoft).
A code reload leak affects your project in the following ways:
The Editor reports a code reload leak a few seconds after a reload finishes, rather than during the reload itself.
The Console window displays a warning about leaked objects from unloading UnityAssemblyLoadContext instances.
The warning has the following form:
Found 1 leaked object(s) from unloading UnityAssemblyLoadContext instance(s)!
Full leak detection report saved to: C:/MyProject/Logs/ALCLeaks.json
Note: use '-record-managed-allocation-callstacks 1' cmdline argument switch to track callstacks for the leaked GCHandles and '-record-managed-allocation-callstacks 2' for GCHandles and objects.
Leaked types:
1 instance(s) of MyGame.AssetIndex
Root kinds:
1 root(s) of kind Handle with None flags
The types under Leaked types are the objects that the Editor can’t release. The entries under Root kinds describe what holds them.
The following are also symptoms of code reload leaks:
For more information on interpreting the leak report Unity generates, refer to Assembly load context leak report reference.