Memory Allocation Strategies for Guests in SharpEmu: Complete Guide to Virtualized Memory Management

SharpEmu implements five distinct memory allocation strategies for guest processes, including a dedicated 64 MiB bump allocator arena, lazy-reserve commit-on-demand for large regions, exact-address placement for ELF segments, and flexible fallback mechanisms, all exposed through the IGuestMemoryAllocator interface.

The par274/sharpemu repository provides a sophisticated virtualization layer that requires careful memory management for guest code execution. Understanding the memory allocation strategies for guests in SharpEmu is essential for developers working with emulated environments, as the codebase implements multiple specialized approaches tailored to different allocation scenarios ranging from fast bump allocations to precise address placement.

The Five Guest Memory Allocation Strategies

SharpEmu's memory subsystem, primarily implemented in src/SharpEmu.Core/Memory/PhysicalVirtualMemory.cs, provides distinct allocation patterns to optimize for different guest workload characteristics.

Dedicated Guest Allocation Arena

The Dedicated Guest Allocation Arena provides fast, contiguous allocations without OS involvement for typical guest memory requests. This strategy uses a fixed-size 64 MiB arena that initializes lazily upon the first allocation request.

When PhysicalVirtualMemory.TryAllocateGuestMemory (lines 300-337) detects an uninitialized arena, it reserves the entire region via AllocateAt with executable:false. Subsequent allocations align the current offset (_guestAllocationOffset) to the requested alignment, verify bounds against GuestAllocationArenaSize, and return base + alignedOffset while bumping the offset forward. This bump allocator pattern ensures O(1) allocation performance and excellent cache locality for guest data.

Lazy-Reserve (Commit-on-Demand) Allocation

For large data regions where the requested size meets or exceeds LargeDataReserveThreshold and exceeds FullCommitRegionLimit, SharpEmu employs a lazy-reserve strategy that minimizes committed memory pages.

The PhysicalVirtualMemory.AllocateAt method (lines 140-210) creates a reserve-only mapping upfront, committing only a configurable "prime" chunk immediately (default 64 MiB, adjustable via the SHARPEMU_LAZY_RESERVE_PRIME_MB environment variable). The remaining pages commit lazily when accessed, preventing unnecessary memory pressure when guests reserve large address spaces for sparse data structures.

Exact-Address Allocation

When loading ELF segments or other scenarios requiring precise placement, PhysicalVirtualMemory.TryAllocateAtExact (lines 67-112) attempts a direct VirtualAlloc call at the specified guest address. This method respects alignment requirements and executable permissions while providing deterministic memory layout. If the exact address is unavailable, callers can implement fallback logic to flexible allocation strategies.

Allocate-At-Or-Above

For allocations requiring specific alignment or minimum address boundaries, PhysicalVirtualMemory.TryAllocateAtOrAbove (lines 48-99) traverses the virtual address space, skipping existing mapped regions, and attempts placement at the first suitable location meeting both the address and alignment constraints. This strategy is crucial for emulating architectures with strict memory layout requirements.

Fallback to Any Address

When specific address constraints cannot be satisfied, SharpEmu falls back to VirtualAlloc(null, …) to obtain any available address region. This occurs as a final resort within the AllocateAt implementation, ensuring allocation requests succeed even when preferred addresses are occupied.

Implementation Architecture

All allocation strategies implement the IGuestMemoryAllocator interface defined in src/SharpEmu.HLE/IGuestMemoryAllocator.cs. The primary implementation resides in PhysicalVirtualMemory, while TrackedCpuMemory (in src/SharpEmu.Core/Cpu/TrackedCpuMemory.cs) provides a wrapper that forwards allocation calls to the underlying memory implementation.

// From PhysicalVirtualMemory.cs
public sealed unsafe class PhysicalVirtualMemory : IDisposable, IGuestMemoryAllocator
{
    private ulong _guestAllocationOffset;
    private const ulong GuestAllocationArenaSize = 64 * 1024 * 1024; // 64 MiB
    
    public bool TryAllocateGuestMemory(ulong size, ulong alignment, out ulong address)
    {
        // Arena initialization and bump allocation logic
    }
}

The TrackedCpuMemory class delegates to the inner allocator:

// From TrackedCpuMemory.cs
public sealed class TrackedCpuMemory : IDisposable, IGuestMemoryAllocator
{
    public bool TryAllocateGuestMemory(ulong size, ulong alignment, out ulong address)
    {
        if (_inner is IGuestMemoryAllocator allocator)
            return allocator.TryAllocateGuestMemory(size, alignment, out address);
        address = 0;
        return false;
    }
}

Practical Usage Examples

Allocate 1 MiB of guest memory with 64-byte alignment using the arena strategy:

IGuestMemoryAllocator allocator = new PhysicalVirtualMemory();
if (allocator.TryAllocateGuestMemory(0x10_0000, 0x40, out ulong guestAddr))
{
    Console.WriteLine($"Guest memory allocated at 0x{guestAddr:X}");
}

Request an exact address for loading an ELF segment at a specific base:

PhysicalVirtualMemory vmem = new PhysicalVirtualMemory();
if (vmem.TryAllocateAtExact(0x4000_0000, 0x2000, executable: true, out ulong exactAddr))
{
    Console.WriteLine($"Exact mapping succeeded at 0x{exactAddr:X}");
}
else
{
    // Handle fallback to flexible allocation
}

Summary

SharpEmu's guest memory subsystem provides sophisticated allocation strategies optimized for virtualization workloads:

  • Dedicated Arena: 64 MiB bump allocator for fast, contiguous allocations without per-request OS calls
  • Lazy-Reserve: Commit-on-demand for large regions with configurable priming to balance memory usage and access performance
  • Exact-Address: Direct placement for ELF loading and architecture-specific requirements
  • Allocate-At-Or-Above: Flexible placement with address space traversal for alignment constraints
  • Fallback Mechanism: Guaranteed allocation success via any available address

These strategies are unified under the IGuestMemoryAllocator interface and implemented primarily in PhysicalVirtualMemory.cs, with TrackedCpuMemory providing transparent delegation for CPU-specific memory tracking.

Frequently Asked Questions

What is the default size of the guest allocation arena in SharpEmu?

The default Guest Allocation Arena size is 64 MiB, defined as a constant in PhysicalVirtualMemory.cs. This arena is created lazily on the first call to TryAllocateGuestMemory and serves as a bump allocator for subsequent guest memory requests.

How does SharpEmu handle large memory allocations for guests?

SharpEmu uses a lazy-reserve strategy for large allocations exceeding LargeDataReserveThreshold and FullCommitRegionLimit. The system reserves the entire region but commits only a small "prime" chunk (default 64 MiB, configurable via SHARPEMU_LAZY_RESERVE_PRIME_MB) immediately, committing the remainder on demand when accessed.

What interface must implementations provide to allocate guest memory in SharpEmu?

Implementations must provide the IGuestMemoryAllocator interface, which includes methods like TryAllocateGuestMemory, TryAllocateAtExact, and TryAllocateAtOrAbove. Both PhysicalVirtualMemory and TrackedCpuMemory implement this interface to provide consistent allocation semantics across the emulation stack.

Can SharpEmu allocate guest memory at specific addresses?

Yes, SharpEmu supports exact-address allocation via TryAllocateAtExact and at-or-above allocation via TryAllocateAtOrAbove. These methods are essential for loading ELF segments and emulating architectures with strict memory layout requirements, though they fall back to flexible allocation if the specific address is unavailable.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →