2.9 KiB
2.9 KiB
Paged Memory Arena Architecture
Status
Implemented & Active (Jan 2026)
Overview
The memory system uses a Paged Arena model backed by global Memory Pools. This architecture supports indefinite growth, efficient clearing, and minimizes OS-level allocations by sub-allocating from large pre-reserved buffers.
Architecture
1. Memory Pool (MemoryPool)
A Global Source of memory blocks.
- Role: Manages a large contiguous memory region (e.g., 512MB for Game).
- Implementation: Free List Allocator.
- Operations:
AllocateBlock(First-Fit with Splitting),FreeBlock(Returns to list). - Optimization: Block Splitting is implemented to preserve free space. If a block in the free list is significantly larger than requested (
Alloc + Header + 16 bytes), it is split, and the remainder is returned to the free list. This prevents pool exhaustion from small allocations consuming large blocks. - Instances:
g_EngineMemory(256MB)g_GameMemory(512MB)g_ScratchMemory(64MB)
2. Memory Arena (MemoryArena)
A High-Level Allocator.
- Structure: A linked list of
MemoryBlocks. - Behavior:
- Growth: Starts with one block. If an allocation exceeds capacity, it requests a new Block (Page) from the backing Pool and links it.
- Alloc: Linear bump-pointer within the current block.
- Clear: Returns all blocks (except the first) to the Pool. Resets the first block.
- Realloc: Supports in-place expansion (if top of stack) or copy-and-move.
- Instances:
GetGameArena(),GetEngineArena(),GetScratchArena().
3. Memory Block (MemoryBlock)
The unit of exchange between Pool and Arena.
- Header: Includes
Magic(debug safety),Nextpointer,TotalSize(renamed fromSize), andUsedoffset. - Alignment: 16-byte alignment enforced.
- Safety: Debug builds use memory poisoning (
0xCDon alloc,0xDDon free) and Magic number checks to detect corruption.
4. Arena Pop (ArenaPop)
Support for LIFO allocations (reclaiming memory).
- Behavior: Checks if the pointer is at the very top of the stack (
CurrentBlock->Used). - Optimization: If valid, decrements
Usedto reclaim space. If not (fragmented), does nothing. - Usage: Critical for
ImGuivector resizing to prevent exponential memory consumption.
Usage
// 1. Get an Arena
MemoryArena* arena = GetScratchArena();
// 2. Push Data
MyStruct* data = ArenaPushType<MyStruct>(arena, "Tag");
void* raw = ArenaPush(arena, 1024, 16, "RawBuffer");
// 3. Pop Data (LIFO)
ArenaPop(arena, raw, 1024); // Reclaims memory
// 4. Reset (Scratch only)
ScratchArenaReset(); // Returns pages to g_ScratchMemory
Migration Status
- ImGui: Migrated to
GetEngineArena()(Paged) withArenaPopsupport for efficient vector resizing. - Display/Window: Uses Engine Arena.
- Game Entities: Uses Game Arena.