Skip to content
Course Content
Heap Common Core

Overview

Windows virtual memory management distinguishes between two separate operations: reserving address space and committing memory. This separation provides flexibility and efficiency in memory management, allowing applications to reserve large address ranges upfront while only committing physical storage as needed.

Reserving Memory

When you reserve memory, you are asking the operating system to set aside a range of virtual addresses for your exclusive use. No physical storage (RAM or page file) is allocated at this point. The reserved address range is simply marked as unavailable for other allocations.

Reserved memory cannot be accessed. Any attempt to read from or write to reserved memory will trigger an access violation exception. To actually use the memory, you must commit it.

Example using VirtualAlloc to reserve memory:

VirtualAlloc(
    NULL,                   // Let system choose address
    0x100000,               // Reserve 1 MB
    MEM_RESERVE,            // Reserve only, don't commit
    PAGE_READWRITE          // Protection (used when committed)
);

Committing Memory

Committing memory allocates physical storage for the virtual addresses. This storage can be in RAM or in the page file on disk. Once committed, the memory can be safely accessed according to its protection flags (read, write, execute).

You can commit memory in two ways:

  • Reserve and commit in a single operation
  • Reserve first, then commit portions later as needed

Example of reserve and commit in one call:

VirtualAlloc(
    NULL,
    0x10000,                        // 64 KB
    MEM_RESERVE | MEM_COMMIT,       // Reserve and commit
    PAGE_READWRITE
);

Example of committing previously reserved memory:

// First, reserve a large region
void* reserved = VirtualAlloc(NULL, 0x100000, MEM_RESERVE, PAGE_READWRITE);

// Later, commit only what we need
void* committed = VirtualAlloc(
    reserved,               // Start of reserved region
    0x10000,               // Commit 64 KB
    MEM_COMMIT,            // Commit previously reserved memory
    PAGE_READWRITE
);

Granularity Rules

Windows enforces specific granularity rules for memory operations:

  • Allocation Granularity (Reserve): Memory reservations must be aligned to 64 KB (0x10000 bytes) boundaries. The system rounds up reservation sizes to multiples of 64 KB.
  • Page Granularity (Commit): Memory commits must be aligned to page boundaries, which are 4 KB (0x1000 bytes) on x86 and x64 systems.

This means you can reserve a 1 MB region and then commit it in 4 KB increments, but the initial reservation must start at a 64 KB boundary.

Why Separate Reserve and Commit?

The separation of reserve and commit provides several benefits:

  • Efficient large allocations: You can reserve a very large address range (like 100 MB) but only commit the portions you actually use, saving physical memory.
  • Contiguous address space: Reserving ensures you get a contiguous block of addresses, even if you commit it piecemeal over time.
  • Dynamic growth: Data structures like stacks and heaps can reserve space for maximum size but commit memory gradually as needed.
  • Memory efficiency: Reserved memory costs virtually nothing (just address space), while committed memory consumes physical resources.

Decommitting Memory

You can decommit memory to release physical storage while keeping the address range reserved. This allows you to reuse the same virtual addresses later without fragmenting the address space.

// Decommit memory, keeping the reservation
VirtualFree(
    address,
    0x10000,        // Size to decommit
    MEM_DECOMMIT    // Decommit but keep reserved
);

Releasing Memory

To completely release memory, you must free the entire reserved region. When freeing, you must pass 0 for the size parameter and use MEM_RELEASE, which decommits and releases the entire reservation at once.

// Release entire reservation
VirtualFree(
    address,
    0,              // Must be 0 when releasing
    MEM_RELEASE     // Release entire reservation
);

Impact on Heap Management

The Windows heap manager leverages the reserve/commit model extensively:

  • Heap segments typically reserve large regions (1 MB or more) upfront.
  • The heap commits pages within these segments as allocations are made.
  • This reduces VirtualAlloc calls, which are expensive system operations.
  • The heap can decommit unused pages to save physical memory while keeping the virtual address range intact.