Download

How to register disregard for GC objects

Feb 22, 2021.Knowledge

How to register disregard for GC objects

Introduction

Following the UE4 object lifecycle, we create objects as needed and destroy them when no longer needed. Destroyed objects are eventually deleted from memory by the garbage collection system (GC). It is useful for object management, but sometimes we do not want to delete objects intentionally. This article indicates how to register objects resident as it relates to this system.

Making an object resident is mainly useful for reducing loading time. By loading or reusing the necessary resources first, you can reduce the chance of having to load them each time. To make an object resident, use “DisregardForGC”.

Note

“DisregardForGC” is a mechanism to keep an object alive permanently by excluding the specified object from garbage collection.
It’s explained in detail in the following slides, which can be downloaded from [Asset Reduction Tools and Optimization Tips for Load Times and GC] on the [Resources] page.

Objects in UE4 are centrally managed in an array (GUObjectArray) that stores all objects.
By enabling DisregardForGC, some of the objects can be stored in a non-GC area. By doing so, certain objects will be excluded from garbage collection and will continue to be retained.

Objects that can be DisregardForGC are those that were loaded during the “period between application startup and the execution of FUObjectArray::CloseDisregardForGC()”. All objects required by the engine are loaded in FEngineLoop::PreInit, and objects used in the project can also be loaded at this timing to make them eligible for resident objects.

Prerequisites

Enable DisregardForGC. (gc.MaxObjectsNotConsideredByGC is non zero).

Example

Here are two example cases of ShooterGame.

Case:1

Load the assets in the constructor of gameInstance. The constructor is executed before DisregardForGC is closed, so the loaded Texture2D object will not be destroyed as a persistent object.

- ShooterGameInstance.cpp
UShooterGameInstance::UShooterGameInstance(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, OnlineMode(EOnlineMode::Online) // Default to online
, bIsLicensed(true) // Default to licensed (should have been checked by OS on boot)
{
UTexture2D* DisregardGCTexture = LoadObject(NULL, TEXT("/Game/Textures/T_ImageB.T_ImageB"), nullptr, LOAD_None, nullptr);
}

Case:2

As another example, it’s also useful to load the file specified in DefaultGame.ini at the timing of PostInitProperties(). In this case, T_ImageA will not be destroyed as a persistent object.

- ShooterGameInstance.h
virtual void PostInitProperties() override;

UPROPERTY(config)
TArray StartupPackages;

- ShooterGameInstance.cpp
void UShooterGameInstance::PostInitProperties()
{
Super::PostInitProperties();
for (FString PackageName : StartupPackages)
{
LoadPackage(nullptr, *PackageName, 0);
}
}

- DefaultGame.ini:
[/Script/ShooterGame.ShooterGameInstance]
+StartupPackages=/Game/Textures/T_ImageA