Back to the map

Module 06 · Memory management · Lesson 1 of 8

Virtual memory

Every process believes it has a large private memory starting at the same addresses. How the OS and hardware create that illusion, what it buys (isolation, sharing, overcommit, files as memory).

CoreMust-knowJunior 12 minVideo Updated Nov 2026
Video walkthrough · 2:35 · narrated, with captions

Why it matters

Virtual memory is the reason two processes can both use address 0x400000 without colliding, why a bug in one program cannot overwrite another's data, why top shows a process with 20 GB of virtual size using 300 MB of real memory, why fork is cheap, and why the out-of-memory killer exists. Container memory limits, page cache behaviour and most "where did my memory go?" questions are answered here.

The idea

Programs never use physical memory addresses. Every address a program uses is virtual, and on every access the CPU's memory management unit (MMU) translates it to a physical address using tables the operating system maintains for that process. Each process gets its own tables, so each has its own private address space: on a 64-bit machine, a range far larger than the physical memory installed.

Process A (virtual)0x40_0000 codeheaplibc codeProcess B (virtual)0x40_0000 codeheaplibc codePhysical RAMframe 17frame 52frame 8frame 3 (shared)
Two processes use the same virtual addresses. Their page tables map them to different physical frames, except where they deliberately share one, such as a shared library's code.

What the indirection buys

BenefitHowWhere you see it
IsolationA process can only reach frames its own tables map; kernel pages are marked inaccessible from user modeA crash or bad pointer stays inside one process
A simple, uniform layoutEvery process sees the same address layout regardless of where its memory physically livesLinkers and loaders can assume fixed regions
SharingMap the same physical frames into several processesShared libraries, the page cache, shared memory IPC
Copy-on-writeShare frames read-only and copy only when someone writesCheap fork; Redis background snapshots
Lazy allocationReserve address ranges now, allocate physical frames on first touchmalloc of 1 GB returns instantly
Files as memoryMap a file's contents into the address space; the kernel pages it in on accessmmap, how executables and databases load data
More memory than RAMMove rarely used pages to disk and bring them back on demandSwap, covered later in this module

Virtual size versus resident memory

Because allocation is lazy and mappings can be shared, three numbers describe a process's memory and they differ wildly. Virtual size (VSZ) counts every reserved range, including untouched heap, thread stacks and mapped files: often huge and mostly meaningless. Resident set size (RSS) counts physical pages currently in RAM for the process, including shared library pages that other processes also count. Proportional set size (PSS) divides shared pages among their users and is the fairest per-process figure. Container memory limits count resident memory (plus page cache charged to the container), which is the number to watch.

Overcommit and the OOM killer

Linux by default lets processes reserve more memory than RAM plus swap, betting that most reservations are never touched. When the bet fails and a page fault needs a frame with none free and nothing reclaimable, the kernel's out-of-memory killer picks a process (scored mostly by memory use) and kills it with SIGKILL. In a container, hitting the cgroup memory limit triggers the same mechanism scoped to the container, which is the usual meaning of exit code 137.

Where the translation lives

The tables are page tables, memory is managed in fixed-size pages (4 KB typically), and a small cache in the CPU, the TLB, keeps recent translations so most accesses do not walk the tables. The next lessons cover each of these, because they explain both the cost of virtual memory and its most common performance pathologies.

Trade-offs

Virtual memory buys isolation, sharing, lazy allocation and a uniform programming model, and costs translation hardware, page-table memory, TLB misses and page faults. Overcommit makes typical workloads more memory-efficient and replaces "allocation failed" errors with sudden OOM kills, which is a harder failure to handle. Almost every general-purpose system accepts these costs; some embedded and real-time systems do not.

In an interview

Use it to read memory numbers correctly and to explain kills: "The pod was OOM-killed at its 2 GB limit, exit code 137. Its virtual size is 9 GB, which is irrelevant; the resident set grew because the cache was unbounded. We bounded the cache and set the limit with headroom over measured peak RSS." That separates people who have debugged memory from people who have read top once.

Check yourself

A service shows 18 GB of virtual memory (VSZ) in top but only 600 MB resident (RSS), on a machine with 8 GB of RAM. Is it about to run out of memory?

Virtual memory · Backplane