One of the biggest challenges for game developers working with Unity is dealing with the garbage collection. The current system they use, Boehm–Demers–Weiser garbage collector drops everything when memory management occurs, which can lead to framerate slowdowns until the garbage collector is done. In an attempt to improve this situation, Unity have implemented Incremental Garbage collection in the most current alpha of Unity 2019.1. Essentially Unity attempts to split memory collection across multiple frames to minimize the impact over all to performance.
Details from the Unity blog:
Enter Incremental Garbage Collection. With Incremental GC, we still use the same Boehm–Demers–Weiser GC, but we run it in an incremental mode, which allows it to split its work into multiple slices. So instead of having a single long interruption of your program’s execution to allow the GC to do its work, you can have multiple, much shorter interruptions. While this will not make the GC faster overall, it can significantly reduce the problem of GC spikes breaking the smoothness of the animation by distributing the workload over multiple frames.
There are however downsides to this approach including greater overhead and possible performance issues if your memory changes during collection.
If you enable incremental GC, the garbage collector will split up the garbage collection work across multiple operations, which can then be distributed across multiple frames. We hope that in most cases where GC spikes were an issue, this will mitigate the symptoms. But Unity content is extremely diverse and can behave in very different ways – and it’s likely that there are cases where incremental GC may not be beneficial.
Specifically, when incremental GC breaks up its work, the part which it breaks up is the marking phase, in which it scans all managed objects to find which other objects they reference, to track which objects are still in use. This assumes that most of the references between objects don’t change between slices of work. When they do change, the objects which have been changed need to be scanned again in the next iteration. This can cause a situation where incremental collection never finishes because it will always add more work to do – in this case, the GC will fall back to doing a full, non-incremental collection. It’s easy to create artificial test cases changing all the references all the time, where incremental GC will perform worse than non-incremental GC.
Also, when using incremental GC, Unity needs to generate additional code (known as write barriers) to inform the GC whenever a reference has changed (so the GC will know if it needs to rescan an object). This adds some overhead when changing references which can have a measurable performance impact in some managed code.
For more information on incremental garbage collection, including step by step instructions on how to enable it, be sure to check out the following video, also embedded below.