void FUObjectArray::CloseDisregardForGC() { check(IsInGameThread()); check(OpenForDisregardForGC); // Iterate over all class objects and force the default objects to be created. Additionally also // assembles the token reference stream at this point. This is required for class objects that are // not taken into account for garbage collection but have instances that are. // Workaround for Visual Studio 2013 analyzer bug. Using a temporary directly in the range-for // errors if the analyzer is enabled. TObjectRange<UClass> Range; for (UClass* Class : Range) { // Force the default object to be created. Class->GetDefaultObject(); // Force the default object to be constructed if it isn't already // Assemble reference token stream for garbage collection/ RTGC. if (!Class->HasAnyClassFlags(CLASS_TokenStreamAssembled)) { Class->AssembleReferenceTokenStream(); } } if (GIsInitialLoad) { // Iterate over all objects and mark them to be part of root set. int32 NumAlwaysLoadedObjects = 0; int32 NumRootObjects = 0; for (FObjectIterator It; It; ++It) { UObject* Object = *It; if (Object->IsSafeForRootSet()) { NumRootObjects++; Object->AddToRoot(); } else if (Object->IsRooted()) { Object->RemoveFromRoot(); } NumAlwaysLoadedObjects++; } UE_LOG(LogUObjectArray, Log, TEXT("%i objects as part of root set at end of initial load."), NumAlwaysLoadedObjects); if (GUObjectArray.DisregardForGCEnabled()) { UE_LOG(LogUObjectArray, Log, TEXT("%i objects are not in the root set, but can never be destroyed because they are in the DisregardForGC set."), NumAlwaysLoadedObjects - NumRootObjects); } // When disregard for GC pool is closed for the first time, make sure the first GC index is set after the last non-GC index. // We do allow here for some slack if MaxObjectsNotConsideredByGC > (ObjLastNonGCIndex + 1) so that disregard for GC pool // can be re-opened later. ObjFirstGCIndex = FMath::Max(ObjFirstGCIndex, ObjLastNonGCIndex + 1); GUObjectAllocator.BootMessage(); } UE_LOG(LogUObjectArray, Log, TEXT("CloseDisregardForGC: %d/%d objects in disregard for GC pool"), ObjLastNonGCIndex + 1, MaxObjectsNotConsideredByGC); OpenForDisregardForGC = false; GIsInitialLoad = false; }