Virtual Memory & Paging
Every process believes it owns a huge private memory. Pages, frames, page tables, the TLB, page faults, memory pressure, memory mapping and copy-on-write.
Every process on the machine believes it owns a large, private, contiguous memory starting at the same address; one level of indirection — a per-process map from virtual pages to physical frames — makes that belief true and buys isolation, relocation, lazy allocation, sharing and protection in a single mechanism.
Process A’s address 0x1000 and process B’s address 0x1000 are two different bytes because each process has its own page table; the address space they see is 48 bits wide, split between a user half and a kernel half that is mapped into every process but unreachable from user mode.
Memory is managed in fixed-size pages: each virtual page maps to a physical frame through an entry carrying present, read/write/execute, dirty and accessed bits, and the "not present" state is not an error but the hook the kernel uses to allocate, share and swap lazily.
The page table is the per-process map from virtual pages to frames; because a flat table for a 48-bit space would be 512 GB, it is a four-level radix tree that exists only where the address space is populated, walked by the hardware from a base register the kernel loads at each context switch.
Walking four levels of page table on every load would make memory five times slower; the translation lookaside buffer caches recent virtual-to-physical translations so that the walk happens once per page per working set — and its reach, its flushes and its tagging decide how expensive huge heaps and context switches really are.
When a translation finds no present page, the CPU traps to the kernel, which classifies the fault — minor (page exists or can be made cheaply: lazy allocation, page cache, copy-on-write), major (read from disk or swap), or invalid (SIGSEGV) — fixes the page table, and resumes the same instruction.
When processes want more memory than the machine has, the kernel reclaims: it drops clean page-cache pages, writes dirty ones back, pushes cold anonymous pages to swap, and — if the working sets still do not fit — kills a process; "free memory" was never the number that mattered.
mmap makes a file appear as a range of the address space — reads become page faults served from the page cache, writes dirty shared pages the kernel flushes later — which is why databases and high-performance systems love it and why its unpredictable stalls and lack of write control make some of them avoid it.
After fork the parent and child share every page read-only; the first write to a page faults, the kernel copies just that page, and the two processes diverge one page at a time — so forking a 10 GB process is cheap until someone writes, which is exactly the property Redis snapshots and process spawning depend on.