// the one-minute version
Many processes share one physical RAM, and none can be trusted with real addresses. The OS, helped by the CPU's memory-management unit (MMU), gives each process its own logical address space and translates it to physical memory on every access. The dominant scheme is paging: chop memory into fixed-size pages and frames so a process's memory can be scattered anywhere — killing the external fragmentation that plagued older contiguous schemes. The TLB keeps translation fast.
Every running program thinks it owns a clean, private block of memory starting at address zero. It doesn't — it shares one physical RAM with dozens of others. The magic that keeps them separate, and frees each from knowing where it really lives, is this chapter.
01 Logical vs physical addresses
The address a program uses is a logical (virtual) address. The actual RAM location is a physical address. They're not the same. On every access, the MMU — hardware in the CPU — translates logical to physical. The program never sees the physical address; it lives entirely in its own virtual world.
02 Address binding
When does "variable x" get tied to a real address? Possibly at compile time (if you know where it loads — rare today), at load time, or — the modern answer — at execution time, with the MMU translating on the fly. Execution-time binding is what lets the OS move a process around in memory freely, which everything below depends on.
03 The old way: contiguous allocation and fragmentation
The simplest scheme gives each process one contiguous block of RAM, bounded by a base and limit register (which also enforce protection — stray outside and the CPU traps). It works, but it rots: as processes come and go, free memory breaks into scattered gaps — external fragmentation — until you have plenty of total free space but no single chunk big enough for a new process.
04 Paging: the winning idea
Split logical memory into fixed-size pages and physical memory into same-size frames (commonly 4 KB). A process's pages can sit in any free frames, scattered all over RAM. A per-process page table maps each page number to its frame number. A logical address splits into a page number (index into the table) and an offset (position within the page). External fragmentation disappears entirely.
Fig 1 — Paging. Contiguous pages in the process map to scattered frames in RAM via the page table. No external fragmentation.
05 Page tables can be huge — so they get structured
A 64-bit address space would need an astronomically large flat page table per process. Real systems use hierarchical (multi-level) page tables (a table of tables, so unused regions cost nothing), hashed page tables, or inverted page tables (one entry per physical frame, not per virtual page). Each trades lookup speed against table size.
06 The TLB: making translation fast
A catch: if every logical access needs a page-table lookup, and the page table is in RAM, then every access becomes two (or more, with multi-level tables). The fix is the translation lookaside buffer (TLB) — a small, very fast cache inside the MMU holding recent page→frame translations. A TLB hit makes translation nearly free; a miss falls back to walking the page table. Thanks to locality, hit rates are very high (often >99%).
07 Segmentation
Segmentation is an alternative (or complement) that splits memory by logical unit — a code segment, a stack segment, a heap segment — each a variable-size piece with its own base and limit. It matches how programmers think and makes protection/sharing per-segment natural, but variable sizes bring back external fragmentation. Modern systems mostly use paging, sometimes with a thin segmentation layer on top (older x86 did both).
common catches & gotchas
- Logical ≠ physical — Programs never use real addresses; the MMU maps every access. Forgetting this breaks your mental model of protection.
- External vs internal fragmentation — Contiguous allocation wastes space between blocks (external); paging wastes a sliver inside the last page (internal). Know which is which.
- Page size is a trade-off — Bigger pages mean smaller page tables but more internal fragmentation; smaller pages, the reverse. There's no universally right size.
- TLB miss ≠ page fault — A TLB miss just means walking the page table (page is still in RAM). A page fault (Chapter 10) means the page isn't in RAM at all. Students conflate them constantly.
- Page table lives in memory too — The table itself takes RAM and an extra access — which is the entire reason the TLB exists.
08 Questions students actually ask
What does the MMU actually do?
On every memory access it translates the program's logical address into a physical RAM address using the page table, and enforces that the access is within the process's memory. It's hardware, so this runs at full speed.
Why is paging better than contiguous allocation?
Paging lets a process's memory be scattered across any free frames, so it never needs one big contiguous hole. That eliminates external fragmentation — the flaw that wastes memory under contiguous allocation.
What problem does the TLB solve?
Without it, each logical access needs a page-table lookup in RAM, doubling (or worse) memory traffic. The TLB caches recent translations so most accesses skip the page-table walk and run at near-full speed.
Internal vs external fragmentation?
Internal: wasted space inside an allocated unit (the partly-empty last page). External: free space exists but is split into chunks too small to use. Paging causes a little internal but eliminates external.
Paging vs segmentation?
Paging uses fixed-size pages and beats fragmentation. Segmentation uses variable, logically meaningful chunks that match how programmers think but reintroduce external fragmentation. Most systems use paging, sometimes with segmentation on top.
09 Key takeaways
- Programs use logical addresses; the MMU translates them to physical on every access — the basis of isolation.
- Contiguous allocation suffers external fragmentation.
- Paging maps fixed pages to scattered frames via a page table, eliminating it (minor internal fragmentation remains).
- Page tables are large, so they're multi-level/hashed/inverted.
- The TLB caches translations so paging stays fast; flushing it makes context switches costlier.
- Segmentation splits memory by logical unit but brings fragmentation back.
10 Wrapping up
Paging gives every process a clean address space mapped onto shared RAM. The real magic comes next: using paging to pretend you have far more memory than you physically own. Next up: Virtual Memory.