SoftGCDenominator
SoftGCDenominator
#Overview
name: SoftGCDenominator
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 SoftGCDenominator is to control the soft garbage collection behavior in Unreal Engine 5’s cooking process. It is used in conjunction with SoftGCStartNumerator to determine the memory threshold at which garbage collection should be triggered during cooking.
This setting variable is primarily used by the Cook-on-the-Fly server, which is part of the UnrealEd module. It is specifically utilized in the UCookOnTheFlyServer class and related cooking systems.
The value of this variable is typically set in the GEditorIni configuration file under the [CookSettings] section. It can be loaded using the GConfig->GetInt() function.
SoftGCDenominator interacts closely with other variables such as SoftGCStartNumerator, bUseSoftGC, and SoftGCNextAvailablePhysicalTarget. These variables work together to manage memory usage during the cooking process.
Developers should be aware that:
- This variable is part of a “soft” garbage collection mechanism, which is different from the standard Unreal Engine garbage collection.
- The actual memory threshold is calculated using both SoftGCStartNumerator and SoftGCDenominator, so they should be adjusted together.
- This setting is only effective when bUseSoftGC is set to true.
Best practices when using this variable include:
- Ensure that SoftGCDenominator is always greater than zero to avoid division by zero errors.
- Adjust SoftGCStartNumerator and SoftGCDenominator together to fine-tune the memory threshold for garbage collection during cooking.
- Monitor cooking performance and memory usage when modifying these values to find the optimal settings for your project.
- Consider the implications on cooking time and memory usage when adjusting these values, as they can significantly impact the cooking process.
#Setting Variables
#References In INI files
Location: <Workspace>/Engine/Config/BaseEditor.ini:377, section: [CookSettings]
- INI Section:
CookSettings
- Raw value:
10
- 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:343
Scope (from outer to inner):
file
class class UCookOnTheFlyServer : public UObject, public FTickableEditorObject, public FExec, public UE::Cook::ICookInfo
Source code excerpt:
int64 SoftGCNextAvailablePhysicalTarget = -1;
int32 SoftGCStartNumerator = 5;
int32 SoftGCDenominator = 10;
bool bUseSoftGC = false;
bool bWarnedExceededMaxMemoryWithinGCCooldown = false;
bool bGarbageCollectTypeSoft = false;
/**
* The maximum number of packages that should be preloaded at once. Once this is full, packages in LoadPrepare will
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:5052
Scope (from outer to inner):
file
function bool UCookOnTheFlyServer::PumpHasExceededMaxMemory
Source code excerpt:
{
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;
}
if (SoftGCNextAvailablePhysicalTarget < -1)
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:5582
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;
NextTarget = FMath::Min(NextTarget, StartNumerator);
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:6903
Scope (from outer to inner):
file
namespace UE::Cook
function void FInitializeConfigSettings::LoadLocal
Source code excerpt:
bUseSoftGC = false;
SoftGCStartNumerator = 5;
SoftGCDenominator = 10;
ReadMemorySetting(TEXT("MemoryMaxUsedVirtual"), MemoryMaxUsedVirtual);
ReadMemorySetting(TEXT("MemoryMaxUsedPhysical"), MemoryMaxUsedPhysical);
ReadMemorySetting(TEXT("MemoryMinFreeVirtual"), MemoryMinFreeVirtual);
ReadMemorySetting(TEXT("MemoryMinFreePhysical"), MemoryMinFreePhysical);
FString ConfigText(TEXT("None"));
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp:6918
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);
MinFreeUObjectIndicesBeforeGC = 100000;
#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:628
Scope (from outer to inner):
file
function FCbWriter& operator<<
Source code excerpt:
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
Writer.EndObject();
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookTypes.cpp:663
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<<
return bOk;
#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/Cooker/CookTypes.cpp:691
Scope (from outer to inner):
file
namespace UE::Cook
function void FInitializeConfigSettings::MoveOrCopy
Source code excerpt:
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:324
Scope (from outer to inner):
file
namespace UE::Cook
Source code excerpt:
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);
friend bool ::LoadFromCompactBinary(FCbFieldView Field, UE::Cook::FInitializeConfigSettings& Value);