<aside> 🗒️ Part of Ari's Unreal Engine Notes.
</aside>
Handling UObjects Outside Game Thread
These are the major stages of the Garbage Collector:
Most of these happen in GarbageCollection.cpp
in CollectGarbageInternal(..)
.
Mark unreachable stage is fully parallel as it just goes through all UObjects via a ParallelFor
and gives them an Unreachable
flag.
This happens in GarbageCollection.cpp
→ PerformReachabilityAnalysis(..)
→ FRealtimeGC::MarkObjectsAsUnreachable
.
The time spent here is logged via LogGarbage
Verbose
in the format %f ms for Mark Phase (%d Objects To Serialize)
.
Mark reachable stage is also a parallel stage where it goes through all root objects and follows all UPROPERTIES recursively to remove the Unreachable
flag on anything that isn't marked as PendingKill
. This happens in FRealtimeGC::PerformReachabilityAnalysisOnObjectsInternal
but all the work is done in TFastReferenceCollector::ProcessObjectArray
. This stage usually takes the most time and is heavily affected by the number of UObjects you have. If you're going over ~100k objects (rough estimate, depends on the project) look into reducing that or taking advantage of GC clusters.
If any object is PendingKill
it will not traverse it and instead null the UPROPERTY reference, so this is where that magic happens and why we have to use IsValid(..)
on UObjects between them being marked as kill and being actually purged.
This stage also calls the overridable AddReferencedObjects
function where you can force other UObjects to not be garbage collected (although I strongly prefer just using UPROPERTIES).
The time spent here is logged via LogGarbage
Verbose
in the format %f ms for Reachability Analysis
.