Operating System Slides 📂 Introduction · 18 of 22 47 min read

Virtual Memory in OS: Demand Paging, Page Faults & Copy-on-Write

Understand virtual memory — running a 4 GB program on 512 MB by loading pages only when touched. Covers demand paging, the valid/invalid bit, page-fault detection and six-step handling, pure demand vs prepaging, the Effective Access Time formula, and copy-on-write fork() — with animated diagrams and two worked numericals.

🪄

Virtual Memory — Demand Paging, Page Faults & Copy-on-Write

The illusion that every process owns more memory than the machine has. See how demand paging loads a page only when it's touched, how the valid bit triggers a page fault, what the OS does to service one, and why a rare fault still dominates access time — with fully animated diagrams and two worked numericals.
Demand Paging Page Faults EAT Maths Copy-on-Write
Press Next → or use ← → arrow keys
SECTION 01

Why Virtual Memory — The Vast Library

Own Ten Million, Shelve One Million
A university library owns ten million books but has shelf space for only one million. It doesn't refuse the other nine million — it keeps them in a warehouse and fetches a book only when someone actually asks for it. To every reader the catalogue looks complete; the shelves just hold whatever is currently in demand. Virtual memory runs a program the same way.
🧠
The Core Idea

A process's logical address space can be far larger than the physical RAM it uses at any moment. Only the pages a program is actively touching need to be resident; the rest wait on disk until referenced. The program sees one big, continuous memory — the illusion of infinite memory.

SECTION 02

What Virtual Memory Buys You

📈
Programs Bigger Than RAM
the killer feature
A 4 GB address space runs on 512 MB of physical RAM — only the "hot" pages need to be resident at once.
👥
More Programs at Once
higher multiprogramming
Each program holds less RAM at a time, so more fit together — CPU utilisation and throughput both rise.
Faster Program Load
start sooner
No need to load the whole binary first — load the first few pages and begin; startup time drops dramatically.
💡
One Mechanism, Three Wins

All three benefits fall out of a single idea: don't keep in RAM what you aren't using. The page table already maps pages to frames — virtual memory just adds the honesty to admit that some pages simply aren't loaded yet.

SECTION 02 · DIAGRAM

Virtual Space, Physical RAM & Disk

Virtual space · 4 GB MMU Physical RAM · 512 MB page 0 page 2 page 5 page M huge — most on disk MMUtranslatevalid? frame f4 · page 0 frame f1 · page 2 frame f7 · page M Disk (Swap)page 5 · not loadedrest of the pages waithere until referenced
🌐
A Few Pages in RAM, the Rest on Disk

The MMU maps resident pages to physical frames (page 0 → f4, page 2 → f1, page M → f7). Pages like page 5 aren't loaded — they live in the swap area on disk until the program touches them. The result: a 4 GB program runs comfortably on 512 MB.

SECTION 03 · DIAGRAM

Demand Paging — Load Only What's Touched

reference pageMMU checks entry valid bit?v → use framei → page fault access dataframe + d HIT OS: find frame → read page from disk → update tablethen restart the instruction — now it's a HIT
🦥
Why "Lazy" Loading Works

Programs obey locality of reference — at any moment they touch a small working set of pages. Loading everything upfront wastes time and RAM on pages that may never run. Demand paging brings a page in only on its first reference, and the valid bit is how the hardware knows the difference.

SECTION 04 · DIAGRAM

The Valid / Invalid Bit

entry: valid = vframe = 6 · in RAM access proceeds ✓physical address computed entry: valid = iframe = — · not in RAM 🛑 PAGE FAULTon disk, or an illegal address
🚦
One Bit, Two Meanings

Each page-table entry gains a valid bit. Set to v, the frame number is real and the access runs normally. Set to i, either the page is on disk and must be brought in, or the address isn't part of the process at all (a bug). The hardware raises a fault and lets the OS decide which.

SECTION 05 · DIAGRAM

Detecting Faults in a Sequence

pageframevalid 04v 16v 2i 32v 4i 57v 6i 70v Access sequence · 0 3 2 5 4 7 page 0HIT f4 page 3HIT f2 page 2FAULT page 5HIT f7 page 4FAULT page 7HIT f0 4 hits · 2 faultsfault rate = 2/6≈ 33% (illustrative)
🔍
The Bit Decides the Path

For each reference the MMU reads the entry: a v yields the frame and completes instantly; an i (pages 2 and 4 here) raises a page fault and hands control to the OS. In real workloads the fault rate must be far below this cold-start figure — the next slides show why.

SECTION 06 · DIAGRAM

Servicing a Page Fault — Six Steps

① traphardware raises fault ② legal?else terminate (SIGSEGV) ③ find framefree one, or evict ④ read diskslow — millions of cycles ⑤ update tableframe set · valid = v ⑥ restartinstruction re-runs → HIT
🛠️
Trap, Fetch, Retry

The OS verifies the address is legal, finds a free frame (evicting a victim if none is free), reads the page from the backing store, marks the entry valid, and restarts the faulting instruction. For this to work the instruction must be restartable — the CPU state is restored exactly as if the fault never happened.

SECTION 07

Pure Demand Paging vs Prepaging

💣
Pure Demand Paging
Start the process with zero pages in memory. The very first instruction faults in page 0, and every new page is another fault. No wasted RAM, but a burst of faults at startup and poor initial performance.
🔥
Prepaging
Load a predicted set of pages before the process runs, batching disk reads for efficiency. The risk: some prepaged pages are never used, so the work is wasted. Modern OSes read ahead by locality.
⚖️
Real Systems Blend Both

Pure demand paging never loads a page that isn't needed but pays many faults up front; prepaging hides latency but risks wasted reads. Production kernels use hybrid heuristics — demand-fault the unknown, read ahead where locality predicts the next pages.

SECTION 08 · DIAGRAM

Effective Access Time for Faults

referencecheck entry no fault · (1 − p)ma = 200 ns page fault · pTfault = 8 ms = 8,000,000 ns a fault is ~40,000× slower than a normal access
# Effective Access Time for demand paging
EAT = (1 − p) × ma  +  p × Tfault      # p = fault probability
    = (1 − p) × 200 ns  +  p × 8,000,000 ns
⏱️
One Rare Fault Dominates Everything

Because a fault (disk) is about 40,000× slower than a RAM access, even a tiny p wrecks the average. A mere 0.1% fault rate multiplies access time roughly . Practical systems need p well below 1 in 100,000.

NUMERICAL 1

EAT at Three Fault Rates

Given ma = 200 ns, Tfault = 8 ms = 8,000,000 ns. EAT = (1 − p)·ma + p·Tfault.

Fault rate pEAT workingEATSlowdown
0.001 (1 in 1,000)0.999×200 + 0.001×8,000,000 = 199.8 + 8,0008,199.8 ns ≈ 8.2 µs≈ 41×
0.0001 (1 in 10,000)0.9999×200 + 0.0001×8,000,000 = 199.98 + 800999.98 ns ≈ 1 µs≈ 5×
target: < 10% slowdownneed EAT ≤ 1.1×200 = 220 nsp ≤ 2.5 × 10⁻⁶≈ 1 in 400,000
# Part (c): largest fault rate for under 10% slowdown
(1 − p)·200 + p·8,000,000 ≤ 220
200 + 7,999,800·p ≤ 220   →   7,999,800·p ≤ 20
p ≤ 20 / 7,999,800 ≈ 2.5 × 10⁻⁶   # about 1 fault per 400,000 accesses
📉
Why Faults Must Be Vanishingly Rare

At 1 fault in 1,000 accesses memory runs 41× slower; even 1 in 10,000 is 5× slower. To keep the slowdown under 10%, the OS must hold faults below 1 per 400,000 accesses — which is exactly what good page-replacement and a healthy working set achieve.

NUMERICAL 2

Translation With Page Faults

Page size 1024 B, 8 pages. Table: 0→3(v), 1→i, 2→1(v), 3→5(v), 4→i, 5→2(v), 6→7(v), 7→i. p = L÷1024, d = L mod 1024.

Logical Lp, dvalid?Physical = f×1024 + d
500p=0, d=500v (f=3)3×1024 + 500 = 3572
1500p=1, d=476iPAGE FAULT
2500p=2, d=452v (f=1)1×1024 + 452 = 1476
4500p=4, d=404iPAGE FAULT
5500p=5, d=380v (f=2)2×1024 + 380 = 2428
🧮
Three Resolve, Two Fault

Addresses landing on valid pages translate straight to 3572, 1476 and 2428. Addresses 1500 and 4500 fall on pages 1 and 4 — both marked invalid, so each triggers a page fault that the OS services before the access can complete.

SECTION 11 · DIAGRAM

Copy-on-Write — Near-Free fork()

Parentpage → frame 9 (RO) Childpage → frame 9 (RO) Frame 9 · sharedread-only · one copy Child writes ✍fault → copy page Frame 14 · privatewritable copy for child
🐣
Copy Only the Page That's Written

After fork(), parent and child share every page read-only. Reads cost nothing. The first write faults; the OS makes a private copy of just that one page, marks it writable, and restarts the write. Pages that are only read — or never touched — are never duplicated, so fork() of a multi-gigabyte process is near-instant.

SECTION 12

Virtual Memory in the Real World

💾
Every Modern OS
Linux · Windows · macOS
All run demand paging plus copy-on-write as the default memory model — it's why your machine runs more than it "fits".
📱
Mobile Devices
Android · iOS
Background apps have their pages paged out to reclaim RAM, and paged back in when you switch to them.
🗄️
Memory-Mapped Files
mmap()
Mapping a file defers disk reads until a page is actually touched — the file streams in on demand via page faults.
📂
Shared Libraries
libc.so
Library code is demand-loaded on first use and shared across processes, so it costs memory only when run.
🐳
Container Startup
Docker · overlayfs
Copy-on-write file systems let containers boot instantly from a shared base image, copying only what they change.
🎮
Game Level Loading
asset streaming
Gigabyte asset files are mmap'd and streamed in as the player moves — only the visible region is ever resident.
SECTION 13

Eight Rules for Virtual Memory

🪄 VIRTUAL MEMORY · CHECKLIST
1
Virtual memory decouples a large logical space from small physical RAM — the illusion of infinite memory.
2
Demand paging loads a page only on first access, trusting locality of reference.
3
Every entry carries a valid bit; clear means "not in RAM" and a reference triggers a page fault.
4
Fault handling: trap → verify → find/evict frame → read disk → update table → restart instruction.
5
A fault costs millions of cycles, so it must be rare — target well below 1 in 100,000 accesses.
6
EAT = (1 − p)·ma + p·Tfault; because Tfault ≫ ma, a tiny p dominates the average.
7
Instructions must be restartable after a fault — the OS restores exact CPU state.
8
Copy-on-Write shares pages read-only and copies only on write — making fork() near-free.
FINAL

The Illusion of Infinite Memory

4 GB / 512 MBLogical over physical
valid bitFault trigger
8 msFault service time
1 / 400kFault budget (<10%)
COWNear-free fork()
🎯
You Now Understand Virtual Memory

From demand paging and the valid bit, through page-fault handling and the EAT maths, to copy-on-write — you can trace any reference, tell a hit from a fault, and compute how a rare disk trip reshapes access time.

📚
Where To Go Next

Virtual memory only works if the OS chooses good victims when RAM is full. Next come the page-replacement algorithms — FIFO, Optimal and LRU — plus Belady's anomaly and thrashing, the heart of keeping the fault rate low.

🪄 End of tutorial · Press to review, or click Restart