Memory Management
5.1 Contiguous Memory Allocation
Fixed partitioning. Memory divided into fixed-size partitions at boot. Internal fragmentation.
Variable partitioning. Partitions created dynamically. External fragmentation.
Allocation strategies:
| Strategy | Description |
|---|---|
| First-fit | Allocate the first hole large enough |
| Best-fit | Allocate the smallest hole large enough |
| Worst-fit | Allocate the largest hole |
| Next-fit | Continue searching from the last allocation |
Theorem 5.1. First-fit and best-fit have roughly equivalent utilisation; first-fit is faster.
5.2 Paging
Divide physical memory into fixed-size frames and logical memory into same-size pages. A page table maps page numbers to frame numbers.
Where is the frame number for page and is the frame size.
Page table entry fields:
| Field | Purpose |
|---|---|
| Frame number | Physical frame containing this page |
| Valid bit | Page is in memory (1) or not (0) |
| Dirty bit | Page has been modified |
| Reference bit | Page accessed recently |
| Protection | Read/write/execute permissions |
Multi-level page tables. A single page table for a 64-bit address space is infeasible. A Two-level scheme uses a page directory indexed by the outer page number, pointing to inner Page tables:
X86-64 with 48-bit virtual addresses uses four-level page tables.
Inverted page table. One entry per physical frame (not per virtual page). Reduces memory Overhead but makes searching for a specific virtual page expensive; solved by hashing.
5.3 Segmentation
Segments divide the address space into logical units (code, data, stack, heap). Each segment has a base and limit:
Advantages: Reflects program structure; supports sharing individual segments. Disadvantages: External fragmentation (variable-size segments).
Worked Example 5.1 — Segmented Address Translation
A process has three segments with the following segment table:
| Segment | Base | Limit |
|---|---|---|
| Code | 4096 | 2048 |
| Data | 12288 | 4096 |
| Stack | 20480 | 2048 |
Translate logical address (segment = 1, offset = 1500):
- Check: offset limit . Valid.
- Physical address = base + offset = .
Translate (segment = 2, offset = 2500):
- Check: offset limit . Invalid — segmentation fault.
5.4 Segmented Paging
Combine segmentation and paging: the segment offset is divided into page number and page offset.
Used by x86 (segmentation + paging).
5.5 Virtual Memory
Virtual memory allows processes to use more memory than physically available by keeping only active Pages in RAM; the rest reside on disk (swap space).
Demand paging. Pages loaded on access, not at process start.
Page fault handling:
- CPU generates logical address; page table entry has valid bit = 0.
- Trap to OS page fault handler.
- Find a free frame (possibly evicting a victim page).
- Read the page from disk into the frame.
- Update page table entry (valid bit = 1, frame number).
- Restart the faulting instruction.
Effective access time (EAT):
Where = page fault rate, = memory access time, = page fault service Time.
For , ns, ms:
This is roughly slower than pure memory access, illustrating why a low page fault rate Is critical.
5.6 Translation Lookaside Buffer (TLB)
A TLB is a hardware cache of recently used page table entries, avoiding an extra memory access Per translation.
Where is the TLB hit ratio.
For , ns, ns:
TLB coherence. When the OS modifies a page table entry, it must invalidate the corresponding TLB entry. On x86-64: invlpg for single-entry invalidation, or reload CR3 to flush the entire TLB.
Worked Example 5.2 — TLB + Page Fault EAT Calculation
A system with TLB access time = 2 ns, memory access time = 100 ns, page fault service time = 8 ms, TLB hit ratio = 0.80, and page fault rate = 0.0005.
Case 1: TLB hit, no page fault (): Time = ns.
Case 2: TLB miss, no page fault (): Time = ns.
Case 3: Page fault (): Time = ns.
This is roughly slower than pure memory access, driven almost entirely by the page fault Component.
5.7 Page Replacement Algorithms
When physical memory is full, a victim page must be selected for eviction.
Optimal (OPT/MIN). Replace the page not used for the longest time in the future. Provably Optimal but requires future knowledge; used only as a benchmark.
Theorem 5.2 (Belady”s Optimality). OPT yields the fewest page faults for any reference string.
Proof. If OPT replaces page (used furthest in future) and another algorithm replaces page (used sooner), the other algorithm faults at least once more by the time is next Referenced.
First-In, First-Out (FIFO). Replace the oldest page. Simple but may evict heavily used pages. Suffers from Belady’s anomaly: increasing frames can increase faults.
Example of Belady’s anomaly. Reference string: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. With 3 Frames: 9 faults. With 4 frames: 10 faults.
Least Recently Used (LRU). Replace the page not used for the longest time. Approximates OPT Well. Does not suffer from Belady’s anomaly.
Theorem 5.3. LRU is a stack algorithm: the set of pages in frames is a superset of the Set in frames, for any reference string.
Proof. When adding a frame, LRU keeps the most recently used pages (same as before) plus the New frame. No page in the -frame set can be more recently used than a page outside it, so the set must contain the -frame set.
Clock (Second Chance). Pages in a circular list with a reference bit. On replacement:
- If reference bit is 0, replace the page.
- If reference bit is 1, clear it and advance.
Approximates LRU with per operation.
LFU (Least Frequently Used). Replace the page with the smallest access count. May fail to adapt To changing access patterns.
Approximating LRU in practice. Most OSes use a variant of Clock. Linux uses an LRU-like Approximation with active and inactive lists: pages on the active list are protected; pages Not accessed are demoted to the inactive list; eviction targets the inactive list.
Worked Example 5.3 — Optimal Page Replacement
Reference string: 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1. Three frames.
| Ref | Frame 1 | Frame 2 | Frame 3 | Fault? | Victim |
|---|---|---|---|---|---|
| 7 | 7 | Yes | — | ||
| 0 | 7 | 0 | Yes | — | |
| 1 | 7 | 0 | 1 | Yes | — |
| 2 | 2 | 0 | 1 | Yes | 7 (used at 18) |
| 0 | 2 | 0 | 1 | No | — |
| 3 | 2 | 3 | 1 | Yes | 0 (used at 10) |
| 0 | 2 | 3 | 0 | Yes | 1 (used at 14) |
| 4 | 2 | 4 | 0 | Yes | 3 (used at 11) |
| 2 | 2 | 4 | 0 | No | — |
| 3 | 3 | 4 | 0 | Yes | 2 (used at 13) |
| 0 | 3 | 4 | 0 | No | — |
| 3 | 3 | 4 | 0 | No | — |
| 2 | 2 | 4 | 0 | Yes | 3 (used at 11, already past) |
| 1 | 2 | 1 | 0 | Yes | 4 (used at ) |
| 2 | 2 | 1 | 0 | No | — |
| 0 | 2 | 1 | 0 | No | — |
| 1 | 2 | 1 | 0 | No | — |
| 7 | 7 | 1 | 0 | Yes | 2 (used at 13, already past) |
| 0 | 7 | 1 | 0 | No | — |
| 1 | 7 | 1 | 0 | No | — |
Total page faults: 9. This is the theoretical minimum.
Worked Example 5.4 — LRU Page Replacement
Same reference string, three frames. LRU replaces the page whose last use was furthest in the past.
| Ref | F1 | F2 | F3 | Fault? | Victim (least recent) |
|---|---|---|---|---|---|
| 7 | 7 | Yes | — | ||
| 0 | 7 | 0 | Yes | — | |
| 1 | 7 | 0 | 1 | Yes | — |
| 2 | 2 | 0 | 1 | Yes | 7 |
| 0 | 2 | 0 | 1 | No | — |
| 3 | 2 | 3 | 1 | Yes | 0 |
| 0 | 0 | 3 | 1 | Yes | 2 |
| 4 | 0 | 4 | 1 | Yes | 3 |
| 2 | 0 | 4 | 2 | Yes | 1 |
| 3 | 3 | 4 | 2 | Yes | 0 |
| 0 | 3 | 0 | 2 | Yes | 4 |
| 3 | 3 | 0 | 2 | No | — |
| 2 | 3 | 0 | 2 | No | — |
| 1 | 1 | 0 | 2 | Yes | 3 |
| 2 | 1 | 0 | 2 | No | — |
| 0 | 1 | 0 | 2 | No | — |
| 1 | 1 | 0 | 2 | No | — |
| 7 | 1 | 0 | 7 | Yes | 2 |
| 0 | 1 | 0 | 7 | No | — |
| 1 | 1 | 0 | 7 | No | — |
Total page faults: 12. LRU produces 33% more faults than optimal, but does not require future Knowledge.
Worked Example 5.5 — Clock (Second Chance) Replacement
Same reference string, three frames. Clock hand starts at frame 0. R = reference bit.
| Ref | State (R bits) | Fault? | Action |
|---|---|---|---|
| 7 | [7,R] [-] [-] | Yes | Load 7 into F0 |
| 0 | [7,R] [0,R] [-] | Yes | Load 0 into F1 |
| 1 | [7,R] [0,R] [1,R] | Yes | Load 1 into F2 |
| 2 | [2,R] [0,R] [1,R] | Yes | F0: R=1, clear, advance; F1: R=1, clear, advance; F2: R=1, clear, advance; F0: R=0, replace with 2 |
| 0 | [2,R] [0,R] [1,R] | No | Set R on F1 |
| 3 | [2,R] [3,R] [1,R] | Yes | F0: R=1, clear, advance; F1: R=1, clear, advance; F2: R=1, clear, advance; F0: R=0, replace with 3 |
| 0 | [0,R] [3,R] [1,R] | Yes | F0: R=0, replace with 0 |
| 4 | [0,R] [4,R] [1,R] | Yes | F0: R=1, clear, advance; F1: R=0, replace with 4 |
| 2 | [2,R] [4,R] [1,R] | Yes | F0: R=0, replace with 2 |
| 3 | [2,R] [3,R] [1,R] | Yes | F0: R=1, clear, advance; F1: R=0, replace with 3 |
| 0 | [0,R] [3,R] [1,R] | Yes | F0: R=0, replace with 0 |
| 3 | [0,R] [3,R] [1,R] | No | Set R on F1 |
| 2 | [2,R] [3,R] [1,R] | Yes | F0: R=0, replace with 2 |
| 1 | [2,R] [3,R] [1,R] | No | Set R on F2 |
| 2 | [2,R] [3,R] [1,R] | No | Set R on F0 |
| 0 | [2,R] [0,R] [1,R] | Yes | F0: R=1, clear, advance; F1: R=1, clear, advance; F2: R=1, clear, advance; F0: R=0, replace with 0 |
| 1 | [0,R] [1,R] [1,R] | No | Set R on F2 |
| 7 | [7,R] [1,R] [1,R] | Yes | F0: R=0, replace with 7 |
| 0 | [7,R] [0,R] [1,R] | Yes | F0: R=1, clear, advance; F1: R=0, replace with 0 |
| 1 | [7,R] [0,R] [1,R] | No | Set R on F2 |
Total page faults: 15. Clock performs worse than LRU here but requires only per operation And no global ordering of references.
:::caution Common Pitfall Belady’s anomaly applies to FIFO but not to LRU or Optimal. Adding more memory does not always Reduce page faults for non-stack algorithms.
5.8 Thrashing
Thrashing occurs when a process spends more time paging than executing. This happens when the Total working set of all active processes exceeds physical memory.
Working set model. is the set of pages referenced in the last references. If available frames, thrashing occurs.
Solutions:
- Working set strategy: Admit a process only if its working set fits.
- Page fault frequency (PFF): Adjust resident set size based on observed fault rate.
- Local replacement: Restrict eviction to the process’s own frames.
Worked Example 5.6 — Thrashing Analysis
A system has 64 frames of physical memory. Four processes with the following working set sizes ( references):
| Process | Working Set Size |
|---|---|
| 15 | |
| 20 | |
| 18 | |
| 25 | |
| Total | 78 |
Total working set = 78 frames, but only 64 available. Thrashing occurs.
Solution 1 (working set admission): Suspend (largest working set). Remaining: . Thrashing eliminated.
Solution 2 (PFF): If ‘s page fault rate exceeds the upper threshold, increase its resident Set size by stealing frames from . If ‘s fault rate drops below the lower threshold, Decrease its allocation.
Theorem 5.4. If the sum of all working sets exceeds the number of physical frames, at least one Process must thrash.
Proof. By the pigeonhole principle, if where is the Total number of frames, at least one process cannot hold its entire working set in memory. That Process will repeatedly evict pages it needs, causing its page fault rate to dominate its execution Time.
5.9 Copy-on-Write (COW)
Copy-on-Write is an optimisation for fork(). Instead of copying all pages, parent and child Share physical frames (marked read-only). On a write to a shared page, a fault triggers a copy of Just that page.
fork()becomes nearly instead of where is the number of pages.- If the child immediately calls
exec()No copies are ever made.
:::