← Operating System Concepts

BOOK NOTES · OPERATING SYSTEMS · CHAPTER 9

Operating System Concepts Chapter 9 — Main Memory.

operating-systemschapter-9memorypagingmmusegmentation

// 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.

key ideaThis split is the foundation of memory protection. Because programs only ever use logical addresses and the MMU does the mapping, one process literally cannot name another's memory. Isolation comes for free from the translation step.

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.

watch outExternal fragmentation is the killer flaw of contiguous allocation. You can have 500 MB free yet fail to load a 200 MB process because the free space is split into 50 MB shards. Compaction (shuffling processes together) helps but is expensive and stalls everything. Paging solves this at the root.

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.

logical (process)page 0page 1page 2page table0 → frame 61 → frame 22 → frame 9physical RAMframe 2 = page1frame 6 = page0frame 9 = page2

Fig 1 — Paging. Contiguous pages in the process map to scattered frames in RAM via the page table. No external fragmentation.

notePaging trades external fragmentation for a little internal fragmentation: the last page of a process is rarely exactly full, so a sliver of its frame is wasted. Averaging half a page per process, this is a tiny, acceptable price.

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%).

watch outThe TLB is why context switches are even more expensive than they look (Chapter 3): switching processes can require flushing the TLB, since the new process has different mappings. The next process then suffers a burst of TLB misses until its hot translations are cached again. Tagged TLBs (with address-space IDs) reduce this.

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.

← prev: Chapter 8next: Chapter 10 →
© cvam — written in plaintext, served warm