Hello!
There is no comprehensive documentation on the internal design of the engine’s allocators. I can share high level details to explain the differences. The short story is that the Ansi allocator is relying on the OS for each memory transaction (allocation\reallocation\free) while the others allocators are using different techniques to save on the system’s overhead.
We need to differentiate the editor from the runtime as their execution context and needs are different. The Editor runs on desktop system that are often more powerful than the target hardware. It also manages source data that is in a format that is easier to manage. We currently use an open source allocator called MiMalloc. This allocator is fairly well documented on its official webpage: mi-malloc: mi-malloc
The runtime allocators are usually the Binned Malloc and the default selection (2 or 3) depends on the platform. Both allocators create pools that manage OS allocated pages. For small allocs (page size /2), the pages are subdivided into bins of constant size so similar size allocations are packed together. The allocator manages the state of the bins (allocated\free) so the behavior at the caller level is the same as classic allocations methods. When allocating, the allocator will look for a page configured with a size that fit the requirement from the call while reducing the waste. This operation is much faster than allocating from the OS as most system will incur extra cost related to virtual addressing. When the allocator cannot find a suitable bin, it simply allocates a new pages and configures it to the proper size. Those sizes are predefined in the headers of the different allocators. Freeing is greatly simplified as it only involves updating the state of the occupied bin. The empty pages are eventually returned to the system to avoid fragmenting the addressing space and running out of RAM.
Large allocations are treated similarly to normal allocations and can just end up being passed to the OS. There can be an extra allocation layer under the binned allocators to manage the pages as some system support up to 1MB. This is defined in CachedOSPageAllocator.h\cpp and add a layer of optimization. The ultimate goal is to reduce the pressure on the OS by reducing the amount of memory related operations since the pooling\caching allows to reuse memory without having to return it to the OS.
The biggest problem that often forces our licensees to use the ANSI allocator is usage of external libraries that rely on DLLs. The engine’s code structure make it that all the standard allocation tokens (New\Delete, Malloc\Realloc\Free) are overloaded and redirected to the engine’s allocator. This creates an incompatibility between the memory allocated by the engine and the memory allocated by the DLL since the memory is not managed the same way. Some libraries allows to inject custom memory management functions and won’t require the usage of the Ansi allocator to be compatible with Unreal.
Regards,
Martin
[Attachment Removed]