SoftGCStartNumerator
SoftGCStartNumerator
#Overview
name: SoftGCStartNumerator
The value of this variable can be defined or overridden in .ini config files. 1
.ini config file referencing this setting variable.
It is referenced in 11
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of SoftGCStartNumerator is to control the soft garbage collection (GC) mechanism in Unreal Engine’s cooking process. It is used in conjunction with SoftGCDenominator to determine the initial memory threshold for triggering a soft garbage collection.
This setting variable is primarily used by the Cook On The Fly Server subsystem, which is part of the UnrealEd module. It’s specifically utilized in the context of memory management during the cooking process for content preparation.
The value of this variable is set in the GEditorIni configuration file under the [CookSettings] section. It can be loaded using the GConfig->GetInt() function.
SoftGCStartNumerator interacts closely with SoftGCDenominator. Together, they form a fraction (SoftGCStartNumerator / SoftGCDenominator) that determines the initial percentage of total physical memory at which soft garbage collection should start.
Developers should be aware that:
- This variable is only relevant when bUseSoftGC is set to true.
- The actual value used is always at least 1, even if set lower in the configuration.
- It’s part of a dynamic memory management system that adjusts GC thresholds based on available memory.
Best practices when using this variable include:
- Ensure SoftGCStartNumerator is smaller than SoftGCDenominator to set a fractional threshold.
- Adjust these values carefully based on the target platform’s memory characteristics and the project’s memory usage patterns.
- Monitor cooking performance and memory usage when modifying these values to find the optimal balance between memory efficiency and cooking speed.
- Consider the relationship between this setting and other memory-related cook settings for a holistic approach to memory management during cooking.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEditor.ini:376, section: [CookSettings]
- INI Section:
CookSettings
- Raw value:
5
- Is Array:
False
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Classes/CookOnTheSide/CookOnTheFlyServer.h:342
Scope (from outer to inner):
file
class class UCookOnTheFlyServer : public UObject, public FTickableEditorObject, public FExec, public UE::Cook::ICookInfo
Source code excerpt:
double LastSoftGCTime = 0.;
int64 SoftGCNextAvailablePhysicalTarget = -1;
int32 SoftGCStartNumerator = 5;
int32 SoftGCDenominator = 10;
bool bUseSoftGC = false;
bool bWarnedExceededMaxMemoryWithinGCCooldown = false;
bool bGarbageCollectTypeSoft = false;
/**
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:5051
Scope (from outer to inner):
file
function bool UCookOnTheFlyServer::PumpHasExceededMaxMemory
Source code excerpt:
if (SoftGCNextAvailablePhysicalTarget == -1) // Uninitialized
{
int32 StartNumerator = FMath::Max(SoftGCStartNumerator, 1);
int32 Denominator = FMath::Max(SoftGCDenominator, 1);
// e.g. Start the target at 5/10, and decrease it by 1/10 each time the target is reached
SoftGCNextAvailablePhysicalTarget = (static_cast<int64>(MemStats.TotalPhysical)*StartNumerator)
/Denominator;
}
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:5581
Scope (from outer to inner):
file
function void UCookOnTheFlyServer::EvaluateGarbageCollectionResults
Source code excerpt:
{
LastSoftGCTime = LastGCTime;
int32 StartNumerator = FMath::Max(SoftGCStartNumerator, 1);
int32 Denominator = FMath::Max(SoftGCDenominator, 1);
// Calculate the new SoftGCNextAvailablePhysicalTarget. Use the floor of NewAvailableMemory/Denominator,
// unless we are already 50% of the way through that level, in which case use the next value below that
int64 PhysicalMemoryQuantum = static_cast<int64>(MemStatsAfterGC.TotalPhysical) / Denominator;
int32 NextTarget =
static_cast<int64>(MemStatsAfterGC.AvailablePhysical - PhysicalMemoryQuantum/2) / PhysicalMemoryQuantum;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:6902
Scope (from outer to inner):
file
namespace UE::Cook
function void FInitializeConfigSettings::LoadLocal
Source code excerpt:
MemoryMinFreePhysical = 0;
bUseSoftGC = false;
SoftGCStartNumerator = 5;
SoftGCDenominator = 10;
ReadMemorySetting(TEXT("MemoryMaxUsedVirtual"), MemoryMaxUsedVirtual);
ReadMemorySetting(TEXT("MemoryMaxUsedPhysical"), MemoryMaxUsedPhysical);
ReadMemorySetting(TEXT("MemoryMinFreeVirtual"), MemoryMinFreeVirtual);
ReadMemorySetting(TEXT("MemoryMinFreePhysical"), MemoryMinFreePhysical);
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:6917
Scope (from outer to inner):
file
namespace UE::Cook
function void FInitializeConfigSettings::LoadLocal
Source code excerpt:
}
GConfig->GetBool(TEXT("CookSettings"), TEXT("bUseSoftGC"), bUseSoftGC, GEditorIni);
GConfig->GetInt(TEXT("CookSettings"), TEXT("SoftGCStartNumerator"), SoftGCStartNumerator, GEditorIni);
GConfig->GetInt(TEXT("CookSettings"), TEXT("SoftGCDenominator"), SoftGCDenominator, GEditorIni);
MemoryExpectedFreedToSpreadRatio = 0.10f;
GConfig->GetFloat(TEXT("CookSettings"), TEXT("MemoryExpectedFreedToSpreadRatio"),
MemoryExpectedFreedToSpreadRatio, GEditorIni);
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:6943
Scope (from outer to inner):
file
namespace UE::Cook
function void FInitializeConfigSettings::LoadLocal
Source code excerpt:
*LexToString(MemoryTriggerGCAtPressureLevel),
bUseSoftGC ? TEXT("true") : TEXT("false"),
bUseSoftGC ? *FString::Printf(TEXT(" (%d/%d)"), SoftGCStartNumerator, SoftGCDenominator) : TEXT(""));
const FConfigSection* CacheSettings = GConfig->GetSection(TEXT("CookPlatformDataCacheSettings"), false, GEditorIni);
if (CacheSettings)
{
for (const auto& CacheSetting : *CacheSettings)
{
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookDirector.cpp:1081
Scope (from outer to inner):
file
namespace UE::Cook
function void FCookDirector::ActivateMachineResourceReduction
Source code excerpt:
*LexToString(COTFS.MemoryTriggerGCAtPressureLevel),
COTFS.bUseSoftGC ? TEXT("true") : TEXT("false"),
COTFS.bUseSoftGC ? *FString::Printf(TEXT(" (%d/%d)"), COTFS.SoftGCStartNumerator, COTFS.SoftGCDenominator) : TEXT("")
);
// Set CoreLimit for updating workerthreads in this process and passing to the commandline for workers
int32 NumProcesses = RequestedCookWorkerCount + 1;
int32 NumberOfCores = FPlatformMisc::NumberOfCores();
int32 HyperThreadCount = FPlatformMisc::NumberOfCoresIncludingHyperthreads();
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookTypes.cpp:627
Scope (from outer to inner):
file
function FCbWriter& operator<<
Source code excerpt:
Writer << "MemoryTriggerGCAtPressureLevel" << static_cast<uint8>(Value.MemoryTriggerGCAtPressureLevel);
Writer << "bUseSoftGC" << Value.bUseSoftGC;
Writer << "SoftGCStartNumerator" << Value.SoftGCStartNumerator;
Writer << "SoftGCDenominator" << Value.SoftGCDenominator;
Writer << "MinFreeUObjectIndicesBeforeGC" << Value.MinFreeUObjectIndicesBeforeGC;
Writer << "MaxNumPackagesBeforePartialGC" << Value.MaxNumPackagesBeforePartialGC;
Writer << "ConfigSettingDenyList" << Value.ConfigSettingDenyList;
Writer << "MaxAsyncCacheForType" << Value.MaxAsyncCacheForType;
// Make sure new values are added to LoadFromCompactBinary and MoveOrCopy
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookTypes.cpp:662
Scope (from outer to inner):
file
function bool LoadFromCompactBinary
Source code excerpt:
}
bOk = LoadFromCompactBinary(Field["bUseSoftGC"], OutValue.bUseSoftGC) & bOk;
bOk = LoadFromCompactBinary(Field["SoftGCStartNumerator"], OutValue.SoftGCStartNumerator) & bOk;
bOk = LoadFromCompactBinary(Field["SoftGCDenominator"], OutValue.SoftGCDenominator) & bOk;
bOk = LoadFromCompactBinary(Field["MinFreeUObjectIndicesBeforeGC"], OutValue.MinFreeUObjectIndicesBeforeGC) & bOk;
bOk = LoadFromCompactBinary(Field["MaxNumPackagesBeforePartialGC"], OutValue.MaxNumPackagesBeforePartialGC) & bOk;
bOk = LoadFromCompactBinary(Field["ConfigSettingDenyList"], OutValue.ConfigSettingDenyList) & bOk;
bOk = LoadFromCompactBinary(Field["MaxAsyncCacheForType"], OutValue.MaxAsyncCacheForType) & bOk;
// Make sure new values are added to MoveOrCopy and operator<<
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookTypes.cpp:690
Scope (from outer to inner):
file
namespace UE::Cook
function void FInitializeConfigSettings::MoveOrCopy
Source code excerpt:
Target.MemoryTriggerGCAtPressureLevel = Source.MemoryTriggerGCAtPressureLevel;
Target.bUseSoftGC = Source.bUseSoftGC;
Target.SoftGCStartNumerator = Source.SoftGCStartNumerator;
Target.SoftGCDenominator = Source.SoftGCDenominator;
Target.MinFreeUObjectIndicesBeforeGC = Source.MinFreeUObjectIndicesBeforeGC;
Target.MaxNumPackagesBeforePartialGC = Source.MaxNumPackagesBeforePartialGC;
Target.ConfigSettingDenyList = MoveTempIfPossible(Source.ConfigSettingDenyList);
Target.MaxAsyncCacheForType = MoveTempIfPossible(Source.MaxAsyncCacheForType);
// Make sure new values are added to operator<< and LoadFromCompactBinary
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookTypes.h:323
Scope (from outer to inner):
file
namespace UE::Cook
Source code excerpt:
int32 MinFreeUObjectIndicesBeforeGC;
int32 MaxNumPackagesBeforePartialGC;
int32 SoftGCStartNumerator;
int32 SoftGCDenominator;
TArray<FString> ConfigSettingDenyList;
TMap<FName, int32> MaxAsyncCacheForType; // max number of objects of a specific type which are allowed to async cache at once
bool bUseSoftGC = false;
friend FCbWriter& ::operator<<(FCbWriter& Writer, const UE::Cook::FInitializeConfigSettings& Value);