Systems
Console Commands & Variables
A console command is sent to the engine to execute a specific functionality.
A console variable is a global state in which data is stored and can be modified through the console.
The supported types are int, float and string.
The following table shows the corresponding C++ types, and the methods to obtain the value of a console variable.
Create a Console Variable
Console variables should be created early when the engine starts, to make sure that auto completion in the editor works.
Therefore, the recommended way to declare a console variable is through static variables.
A console variable is declared with the TAutoConsoleVariable template type and the template argument represents the data type of the variable.
A console variable is created with a name, a default value, a description, and EConsoleVariableFlags flags.
The flags are defined in IConsoleManager.h.
static TAutoConsoleVariable<int32> CVar(
TEXT("MyVariable"),
42,
TEXT("A variable"),
ECVF_Cheat);Consoles variables can also be created by calling the IConsoleManager::RegisterConsoleVariable function.
The global instance of the console manager is accessed using IConsoleManager.Get().
IConsoleManager::Get().RegisterConsoleVariable(
TEXT("MyCVar"),
42,
TEXT("A variable"),
ECVF_Cheat);Access a Console Variable
The most efficient way to access a console variable is perform a look up with IConsoleManager::FindConsoleVariable and store the result in a static variable.
As console variables persist during the lifetime of the project, it is safe.
static const auto MyCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("MyCVar"));
int32 Value = MyCVar->GetInt();Command-Line
The value of console variables can be set when starting the editor using the -ExecCmds argument.
UE4Editor.exe GAMENAME -ExecCmds="r.MyCvar 42"Memory Allocators
Allocation Rules
Blocks equal or larger than 16 bytes are 16-byte-aligned.
Blocks smaller than 16 bytes are 8-byte aligned.
Global Allocators
The global allocator is GMalloc. It is a FMalloc allocator.
The instance to the global allocator is platform-dependent.
It is accessed using FPlatformMemory::BaseAllocator.
On most platforms, it returns the ANSI malloc implementation represented by FMallocAnsi.
FMallocAnsi performs aligned allocations using a platform-dependent function such as _aligned_malloc (Microsoft), posix_memalign (Apple, Linux, Web), or memalign (PS4).
On platforms that do not provide aligned allocations, the allocation falls back to a regular malloc call with custom padding.
On some platforms, the default base allocator can be replaced with a different implementation using specific preprocessor symbols or command-line options.
The other allocators are:
- Binned, Binned2
- Binned3 (64-bit only)
- TBB (Windows and macOS)
Containers
There are different allocation policies for containers, represented by allocator traits.
The base template type for traits is TAllocatorTraits.
It actually derive from the non-template type TAllocatorTraitsBase.
FHeapAllocator– Always allocates the elements indirectly.
TAlignedHeapAllocator– Similar toTHeapAllocatorbut supports aligned allocations with anAlignmentparameter.template<uint32 Alignment> TAlignedHeapAllocator< Alignment >
TInlineAllocator– Allocates up to a specified number of elements in the same allocation as the container, and falls back to a secondary container when the number of inline elements is reached.template<uint32 NumInlineElements, typename SecondaryAllocator> TInlineAllocator< NumInlineElements, SecondaryAllocator >NumInlineElementsis the number of inline elements.
SecondaryAllocatoris the fall back allocator. By default, it isFDefaultAllocator.
TFixedAllocator– Allocates up to a specified number of elements. There is no secondary storage when the number of inline elements is reached.template<uint32 NumInlineElements> TFixedAllocator< NumInlineElements >
TSetAllocator– Encapsulates the allocators used by a set. By default, it is aTSparseArrayAllocator.
Low-Level Memory
Memory allocations are tracked by the Low-Level Memory (LLM) Tracker.
Every memory allocation is assigned a tag value identifying the category to which it belongs.
The tags are applied using tag-scope macros.
LLM is stripped out of Shipping builds.
Usage
To enable LLM, launch the project with the -LLM Enables command-line argument.
To continuously writes out all values to a CSV file, use the -LLMCSV argument instead.
There are two trackers represented by the ELLMTracker enumerated type: Default and Platform.
The Platform tracker is used by the platform-dependent modules such as Windows, macOS, Direct3D, Metal, Vulkan, and so on.
There are two corresponding scope macros:
LLM_SCOPE– Default tracker.
LLM_PLATFORM_SCOPE– Platfom tracker.
The macros are called with the tag to associate with the allocations.
Tags are represented by the ELLMTag enumerated type.
Example
In FAssetRegistryModule::StartupModule, the scope macro is used with the AssetRegistry tag.
void FAssetRegistryModule::StartupModule()
{
LLM_SCOPE(ELLMTag::AssetRegistry);
...
}Implementation
LLM maintains a map of all allocations indexed by a pointer.
LLM uses 21 bytes per allocation.
| Allocation | Size |
|---|---|
| Pointer | 8 bytes |
| Pointer Hash Key | 4 bytes |
| Size | 4 bytes |
| Tag | 1 byte |
| Hash Map Index | 4 bytes |
The memory used by LLM is managed by the LLMAlloc and LLMFree functions.
Add a New Tag
- Add a value to the
ELLMTagenumerated type inLowLevelMemTracker.h.
- Add a corresponding element to the
ELLMTagNamesarray inLowLevelMemTracker.cpp.
- Add tag scopes using the
LLM_SCOPEmacro.