Garbage Collector Internals (Epic KB, Ari Arnbjörnsson, Staff)
- "standard Mark & Sweep collector". Stages: Mark unreachable, Mark reachable, Sweep, Shrink Hash Table; mostly in GarbageCollection.cpp CollectGarbageInternal.
- Analytics:
log LogGarbage verbose,gc.DumpAnalyticsToLog 1. - Mark Unreachable: since UE 5.4 a single flag swap (before: ParallelFor over all UObjects).
- Mark Reachable: parallel; from root objects follows all UPROPERTIES recursively, clearing Unreachable on anything not PendingKill (UE4)/Garbage (UE5); usually takes the most time, heavily affected by UObject count — over ~100k objects (rough) consider reducing or GC clusters. Calls AddReferencedObjects.
- Pending Kill / IsGarbage: GC can destroy referenced objects marked garbage (e.g. after Destroy()) and nulls UProperties referencing them. UE5 option gc.GarbageEliminationEnabled=false (formerly gc.PendingKillEnabled) — then only unreferenced objects are destroyed; "will eventually disable that as the default, probably in some UE6 version. Lyra already has this disabled." With it disabled, IsValid() still false for garbage objects, but memory isn't released until you null strong C++ references (BP references still cleared) — listen to OnEndPlay or use soft/weak pointers.
- Sweep: IncrementalPurgeGarbage; full purge if bPerformFullPurge; level streaming out may force it — s.ForceGCAfterLevelStreamedOut 0 (World Partition turns it off automatically).
- Shrink Hash Table: FUObjectHashTables::ShrinkMaps; log "Compacting FUObjectHashTables data took".