<aside> 🗒️ Part of Ari's Unreal Engine Notes.

</aside>

Sub Pages

Invalid object in GC

Handling UObjects Outside Game Thread

Garbage Collector Internals

These are the major stages of the Garbage Collector:

Most of these happen in GarbageCollection.cpp in CollectGarbageInternal(..).

Mark Unreachable

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.cppPerformReachabilityAnalysis(..) → 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

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.