Skip to content

Subsystem · Pages, maps, and compression

Virtual Memory

Pmap, VM map, the compressor, jetsam — how XNU gives every process a private address space without ever running out of RAM.

Virtual memory: vm_map, vm_object, pmapA task's vm_map is a sorted list of entries pointing at vm_objects, which know where each page lives (RAM, compressor, swap, or a backing file). The pmap installs the actual hardware page-table entries.PER-TASK · MACHINE-INDEPENDENTvm_maposfmk/vm/vm_map.h0x0001…0x1000→ vm_object · stack0x4000…0x6000→ vm_object · heap0x7000…0x9000→ vm_object · mmap libfoo.dylib0xc000…0xd000→ vm_object · anonymousPAGE BACKINGanon vm_objectzero-fill on first touchanon vm_objectvnode vm_objectmmap'd dylibanon vm_objectreclaimablePER-TASK · MACHINE-DEPENDENTpmaposfmk/arm/pmap.cL1 / L2 / L3 PTEshardware page tablesASID + TTBR0task's translation regimeAPRR / SPRRW↔X switchingWHERE COLD PAGES GOVM compressorWKdm in-RAMswap files/private/var/vm/swapfile*evict to filevnode_pager · text pages
Virtual Memory: structure at a glance.

Articles in this series

Every macOS process gets a private address space it can't possibly afford. Here's how XNU gives it one anyway — pmap, vm_map, the compressor, and jetsam.
Walk a single mmap call from libc, through BSD into Mach VM, the lazy first-touch fault, and the pmap entry that finally makes the file accessible as memory.
How XNU responds when memory gets tight — the four-stage pressure pipeline from free pages through compression to swap to process termination, and what each stage costs.
The kernel's own malloc — a hierarchy of zone allocators, the kalloc heap, and slab caches for specific types. Different from user-side VM, and just as important.
Every system dylib pre-linked into one giant memory-mappable file, shared across every process on the system. Why a fresh process has 1 GB of virtual size but tiny resident memory.