Memory Management: Paging, Virtual Memory, Page Replacement, Segmentation, and Thrashing
13.1 Paging Review: Pages, Frames, and the Page Table
Hook — why paging? A running process needs its code and data in memory, but free memory rarely comes as one unbroken strip of exactly the right size. What if a process could be cut into equal pieces, and each piece stored in whatever slot has room? Paging is exactly that idea, and it is the memory scheme behind nearly every modern operating system.
13.1.1 Pages, Frames, and Address Translation
Paging splits a process into fixed-size pieces called pages. Each page carries a number, and that page number maps directly into a frame number. A frame is a fixed-size slot in physical memory, and the frame size always equals the page size. The two names never blur: the frame number always corresponds to physical memory, while the page number corresponds to the virtual (logical) address space — everything from the user's point of view. The CPU generates a logical address for every instruction fetch and every data access, and that logical address must be converted into a physical address before the memory can be touched for execution.
The mapping, or translation, between pages and frames is done by a page table: a table with one entry per page, where each entry stores the frame that currently holds that page. Whatever the number of pages a process has, those pages are placed into physical memory with the help of frames, and every lookup ends in a base-plus-offset calculation: take the frame number as a base, convert it into bytes by multiplying by the frame size, and add the offset — the distance inside the page — to reach the exact location.
The translation formula. A logical address is split into two parts: a page number and an offset. The page number selects the page table entry; the entry supplies the frame number; and the physical address is
- Page number — which page of the process the address touches; it indexes the page table.
- Frame number — the slot in physical memory that currently holds that page; it is read from the page table entry.
- Frame size — the size of one frame, always equal to the page size.
- Offset — how far inside the page (and so inside its frame) the byte sits. It ranges from 0 up to (page size − 1), so the offset range is governed by the limit — the page size.
An everyday picture helps: think of a textbook cut into equal chapters and a library shelf cut into equal slots. The chapters are the pages, the slots are the frames, and the page table is the index card that tells you which slot currently holds chapter 7. The analogy breaks in one place: the index card is printed once, while a page table is rewritten by the operating system every time a page moves to a different frame.
Scope — when does the formula apply?
- The frame size must equal the page size. The formula works because every frame starts at a multiple of the frame size, so multiplying the frame number by the frame size gives the frame's first byte.
- The page table must hold one entry per page, and the page number must be a legal index into it. A page number outside the table is caught by the valid/invalid bit discussed in Section 13.1.3.
- This formula maps addresses only. Whether the page is actually sitting in its frame is a separate question — the one that virtual memory and page faults answer in Section 13.3.
Visually, the setup has two columns. On the left, the process's logical address space is sliced into equal blocks labeled page 0, page 1, page 2, …; on the right, physical memory is sliced into equal frames labeled 0, 1, 2, …. Arrows leave each page and land on a different frame, and the arrow's destination is stored in the page table. Because pages and frames are the same size, the pieces fit together like blocks into matching holes, with no irregular gaps between them.
Common pitfalls
- Mixing up the two sides of the mapping: a page number names a page in the logical address space, while a frame number names a slot in physical memory. A page number can never be used directly as a physical location, and a frame number is meaningless to the process.
- Forgetting that translation happens on every memory access — instruction fetches and data accesses alike — not just on occasional ones.
- Using the offset alone as the physical address. The offset only locates the byte inside the frame; the frame base must be added first.
- Confusing the base (frame number × frame size) with the page table base register from Section 13.1.3 — one is a frame's start address, the other points to the page table itself.
Recap. Paging slices both the process and physical memory into equal fixed-size blocks — pages on the logical side, frames on the physical side — and a page table records which frame holds each page. The physical address of any byte is its page's frame base plus the offset inside the page.
13.1.2 Worked Example: A Four-Page Process Mapped to Frames
The mapping is worth doing once slowly, in full, with real numbers.
Worked example — a four-page process mapped to frames.
Given: each page holds 4 values; the process has four pages; page 0 maps to frame 5 and page 1 maps to frame 6.
- Page 0 → frame 5. Frame base: . The frame starts at physical address 20, and its 4 bytes cover addresses 20, 21, 22, 23.
- Page 1 → frame 6. Frame base: . Its 4 bytes cover addresses 24, 25, 26, 27.
- The values in page 0 — say A, B, C, D — sit consecutively at addresses 20, 21, 22, 23.
- The values in page 1 — say 4, 5, 6, 7 — sit at addresses 24, 25, 26, 27.
- The pattern repeats for every page: page 2 → frame 7 gives base (addresses 28–31), and page 3 → frame 8 gives base (addresses 32–35).
The narrative while solving: from the base number, the offset is calculated to find the exact location inside the page; each page maps to its frame through the page table, and the page table entry is what tells you which frame holds which page.
Sense-check: every frame base is a multiple of the page size (20, 24, 28, 32), and each page's values occupy four consecutive addresses inside its frame. A byte at offset 2 of page 0 lives at — inside the frame, as the formula promises.
13.1.3 Page Table Hardware and the TLB
Because the CPU translates an address on every single memory access, translation must be fast. To keep it fast, we add a small hardware cache called associative memory, or the translation look-aside buffer (TLB). The TLB stores pairs of page numbers and their frame numbers — it is a cache of page table entries. It is tiny: the entries typically range from a minimum of 64 to a maximum of 1024. When the CPU produces a logical address, the page number is looked up in the TLB first. If it is found — a TLB hit — the frame number comes with it, the offset is appended, and the physical address is ready. If the page number is not in the TLB — a TLB miss — the lookup falls through to the page table.
Why is the TLB needed at all? Because the page table always lives in main memory. To find an entry you need two registers: a base register that points to the start of the page table, and a page table length register (PTLR) that holds the size of the page table. To access one instruction or one piece of data you need two memory accesses: the first goes to the page table to fetch the frame number, the second goes to the frame itself to fetch the data or instruction. That doubling is the price of paging — and the TLB is the cure, because a hit replaces the first memory access with a fast cache lookup.
If the page is not in the page table either, it lives on secondary storage, and we must bring it in with a page replacement policy — the topic of Section 13.4. The hardware support needed for paging is exactly this: the base register, the length register, and the associative memory. The valid/invalid bit protects the table as well: before trusting an entry, the system checks whether the page is legal and present.
Real-world: the TLB is the hardware cache inside the processor that makes address translation fast; without it, every single memory access would be doubled by page-table lookups. The percentage of translations found in the TLB is called the hit ratio, and on real processors it is well above 95% — that is why paging costs so little in practice. The hit ratio is so important that modern designs use larger pages (2 MB or even 1 GB "huge pages") just to make each TLB entry cover more memory.
Common pitfalls
- Treating the TLB as the page table: the TLB is only a small cache of the most recent translations; the page table in memory is the authority, and a TLB miss simply falls back to it.
- Confusing a TLB miss with a page fault: a miss means the translation was not cached and the page table must be consulted; a page fault happens only when the page table entry is invalid, meaning the page is not in memory at all.
- Forgetting the validity check on a TLB hit: the entry could belong to a page that was since swapped out, so the valid/invalid bit must still protect the lookup.
- Assuming the TLB eliminates the page table: the page table still exists and is still consulted on every miss.
13.1.4 Page Size Trade-offs and Frame Allocation
The page size is usually 4 KB to 8 KB, with 4 KB being the standard on x86 systems. The choice of page size matters for three things: how much space is wasted to internal fragmentation, how many entries the page table needs, and how efficient disk I/O is. Paging is a form of dynamic relocation, and because pages and frames are fixed-size blocks, there is no external fragmentation — the gaps between allocations simply do not exist. The page size decides how much leftover space inside a page is wasted, which is internal fragmentation.
| Property | Small pages | Large pages |
|---|---|---|
| Page table entries | more (one per page) | fewer |
| Internal fragmentation | less — a nearly empty page wastes little | more — a page may include space the process never uses |
| Disk I/O per transfer | smaller transfers | more efficient — one transfer moves more data |
When to pick which: small pages fit processes with sparse memory use; large pages win when big sequential data dominates, because the I/O savings and the smaller tables outweigh the wasted space inside pages.
A frame table keeps track of which frames are allocated and which are free. When a new process arrives, it takes frames from the pool of free frames. Consider a process with four pages and five free frames. The pages are assigned to frames from the free pool: page 0 goes to frame 14, page 1 to frame 13, page 2 to frame 18, and page 3 to frame 20, leaving one frame free for other processes. The first thing to do after any allocation is to make the page table entry: page 0 now maps to frame 14, page 1 to 13, and so on. That entry is the only link the system uses later to translate addresses for that process — allocate the frame, then record the mapping, before anything else touches the page.
Recap + bridge. Paging maps pages to frames through a page table, translates every address as frame base plus offset, and pays two memory accesses per access unless a TLB catches the translation. Page size balances internal fragmentation, table size, and disk I/O. With the mechanism in place, the next step is counting bits: how many bits a logical address needs, how many frames fit in physical memory, and how big the page table must be.
13.2 Worked Problem: How Many Bits in a Paging System
Hook — sizes decide bits. A paging system gives you three sizes: physical memory, page size, and the number of pages in the logical address space. From nothing but those three numbers, you can answer how many bits the logical address needs, how many frames physical memory holds, and how big the page table must be. This exact problem pattern recurs on exams.
13.2.1 The Setup and the Formulas
The setup of the problem is simple and recurring. A paging system has:
- physical memory of bytes,
- a page size of bytes,
- a logical address space of pages, with each page of size .
Two formulas do all the work. The first: the size of the logical address space equals the page size times the number of pages in the logical address space, and the number of bits in the logical address is the base-2 logarithm of that size. The second: the same idea applies to the physical address, only with different values — the physical address space is the number of frames times the frame size. Remember that the frame size always equals the page size.
The two working formulas.
Because all sizes here are powers of two, the number of bits is just the exponent: a space of bytes needs 26 bits, a space of bytes needs 32 bits. In general, bits = .
13.2.2 All Five Answers Worked Out
The five questions chain together: each answer feeds the next — address space, then bits, then frames, then entries, then bits per entry.
Worked example — the five answers, step by step.
Question 1 — How many bits are there in the logical address? The logical address space has pages, and each page is bytes, so:
That is bytes, which means 26 bits are needed to form the logical address. Note the careful distinction: the address space is the whole -byte collection, but the address is the individual 26-bit value used to point inside it.
Question 2 — How many bytes are there in a frame? The frame always mirrors the page: the size of the frame equals the size of the page, which is bytes. Since needs 10 bits, the number of bits present in the frame is 10.
Question 3 — How many bits in the physical address specify the frame? Apply the same formula to the physical side: the size of the physical address space equals the number of frames times the size of the frame. The total physical address space is known: bytes. The number of frames is then:
So 22 bits of the 32-bit physical address represent the frame number, and the remaining bits represent the offset within the frame. The offset width is 10 on both sides, because the frame size equals the page size.
Question 4 — How many entries are there in the page table? There are pages in the logical address space, and every page needs its own entry, so the page table has entries.
Question 5 — How many bits are in each page table entry? Each entry stores the frame number of its page. The frame number uses 22 bits, so each and every page table entry also carries 22 bits. (Real systems add extra bits — valid/invalid, protection, dirty — but for this problem the answer is exactly 22.)
Q: We found 26 bits for the logical address — isn't that the answer itself? A: No. The address space is the whole collection of bytes; the address is the 26-bit value used to point inside it. Address is not address space. We need 26 bits in order to form the logical address. The space is measured in bytes; the address is measured in bits — the exponent of the space size.
Exam note: this exact question pattern — how many bits, how many frames, how many entries — is core paging material. The answer to question 5 reuses the answer to question 3, so the steps chain: address space → bits → frames → entries → bits per entry. Work the chain in order and each answer falls out of the previous one.
Scope — when the arithmetic works:
- The powers of two make bits = exponent. With non-power-of-two sizes, use bits and round up.
- The offset is 10 bits wide only because the page size is . A different page size changes the offset width on both the logical and the physical side.
- "Bits per page table entry" here means the frame-number width. A full design also carries protection and validity bits; the exam question counts only what the entry must store to do translation.
Common pitfalls
- Answering "the logical address space is 26 bits": the space is bytes; the address is 26 bits. Same digit, different quantities.
- Confusing the number of pages () with the number of frames (): pages live in the logical space, frames in physical memory.
- Forgetting that question 3's answer is the frame-number bits only — the remaining 10 bits of the 32-bit physical address are the offset.
- Writing as "26 bytes": the exponent is bits, the base-2 value is bytes.
13.2.3 Practice Question with Given Answers
A second problem of the same kind was shared with answers already given; you can try it later on your own and check. Work through the same five questions — logical address bits, frame bytes, physical address frame bits, page table entries, and bits per entry — using the same two formulas.
To make the pattern stick, try this self-check variant: a system with physical memory of bytes, a page size of bytes, and a logical address space of pages. Working the chain: → 32-bit logical address; frame size → 12 bits per frame; frames → 24 frame bits and offset bits; page table entries; 24 bits per entry. Run the same five steps on the shared practice question and check every answer the same way.
13.3 Virtual Memory and Demand Paging
Hook — bigger than the machine. A computer has 8 GB of physical memory, yet a single program can demand far more than that and still run. The program seems to have all the memory it needs — the machine just cannot tell the difference. That trick is virtual memory, and it is why the degree of multiprogramming can be raised without exhausting the machine.
13.3.1 What Virtual Memory Is and Why We Need It
Virtual memory seems to exist, but really does not exist — that is the meaning of virtuality. It is a technique that allows the execution of processes that are not completely in memory. Physical memory size cannot be increased; whatever is there will only be there. Yet we can still run many processes, and the reason the degree of multiprogramming — the number of processes present in memory at any time — can be raised is exactly this technique.
Why go to virtual memory? Several motivations. Programs declare tables, arrays, and lists, and each process needs all of those allocated, so the memory needed can exceed what is present. The principle of locality (discussed in Section 13.6) means only part of a program is actively used at any moment. And unusual conditions must be handled by programs that need to be present in memory. The advantages follow: there is no constraint from the amount of physical memory available, because each program does not actually take that much memory and not all programs run at the same time; throughput and CPU utilization both increase; programs that are not necessary can be swapped out of memory to make room, and other programs can be brought in and made to work faster.
Virtual memory in one sentence. A process runs even though only part of it sits in physical memory; the rest waits on secondary storage and is brought in only when needed. The logical address space is separated from the physical address space: a program that is very big does not sit wholly in main memory — only the part needed for execution is there. Always, the logical address space is greater than the physical address space, and only certain portions are shared by the processes.
A theatre analogy captures the split: the act seems to have every prop it needs, but only the props currently on stage are in memory; the rest wait backstage in storage and are carried out only when a scene needs them. Mapping: the stage is physical memory, the storage room is the swap device, and the props are pages. The break point: hauling a prop from storage takes time — that is the page fault cost that Section 13.3.4 measures.
Inside the virtual address space, the data and the code occupy their regions, and the remaining space is left for the stack and the heap: the stack always grows down and the heap always grows up. They start at opposite ends of the address space and grow toward each other, which gives both room to grow without a fixed boundary.
Scope — when does virtual memory help?
- It leans on locality: if a program truly touched every one of its pages constantly, virtual memory would add only overhead. Real programs concentrate references in a few pages at a time, so only a fraction of each process is resident.
- "Logical address space greater than physical" is the demand-paging setting. In pure (non-demand) paging, all pages of a process must be resident before it runs.
- The logical address space is bounded by the address width, not by the amount of RAM installed.
Real-world: this is how every modern operating system lets programs bigger than the installed physical memory still run, and why adding processes raises utilization instead of exhausting memory. A browser with many open tabs is the everyday example — every tab runs with its own large virtual address space, while the physical frames are shared and only the pages in active use stay resident.
13.3.2 Demand Paging and the Lazy Swapper
Bringing in a page only when it is needed is demand paging, and it is done by a lazy swapper. The lazy swapper never swaps a page into memory unless that page is needed; the swapper used for this kind of paging is called the pager. When a page or a set of pages is not required, it is swapped out to secondary storage, and only the pages necessary for execution are brought from secondary storage into memory. That selective swapping is how virtual memory is implemented.
The advantages of demand paging: less I/O is needed, less memory is needed, responses are faster, and more users can be served at a time.
The valid/invalid bit makes demand paging work. In the page table, one bit tells whether the page is valid or invalid: valid means the page is in memory, invalid means it is not.
- Initially all pages are set to invalid (I) — the process starts with nothing resident.
- Later, when a page is brought into memory, an entry is made in the page table and the bit is set to valid (V).
- When address translation takes place and the entry is invalid, that is a page fault: a reference to a page that is not in memory. Execution is only possible if the page is in main memory, so the page must be brought in.
Consider the example from the lecture: page 7 corresponds to some data value H, and only three pages — A, C, F — are physically present. When page 7 is referenced, the page table entry has no frame and the bit is invalid, meaning page 7 is not in main memory. Execution can only continue if the page is brought in first.
Common pitfalls
- Reading "invalid" as "illegal": invalid means not present in memory; an illegal address (outside the process's address space) is a different failure. On a fault the operating system checks both — legality first, presence second.
- Confusing the pager with the classic swapper: the old swapper moved whole processes in and out; the pager moves single pages, only when needed.
- Assuming demand paging means pages enter memory by prediction. Demand paging brings pages in only on demand — prefetching is a separate optimization, not the default.
13.3.3 What Happens on a Page Fault
A page fault starts in hardware and ends in the operating system. The full sequence, in order:
- A reference is made to a page whose entry is invalid.
- A trap is made to the operating system.
- The operating system checks whether this is an invalid reference (an illegal address) and confirms the page is genuinely not in memory.
- The system finds a free frame.
- The page is brought in: a read request is issued from the disk to the free frame, and the request waits in the queue until it is serviced — the disk needs seek time and latency time before the transfer itself.
- Once the free frame is found and the transfer completes, the page table is reset: the bit is set to valid and the frame number is placed in the entry.
- The instruction is restarted.
Purpose of the sequence. The page fault service is the heart of demand paging: the hardware detects the missing page and interrupts, the operating system arranges the disk read and updates the page table, and the interrupted instruction is restarted as if nothing happened. Without step 7 the process would lose an instruction; without step 3 a bad address could cause a wild disk read.
Inside those steps, much happens that we do not need to worry about in detail: when the trap is made, the user registers save the state of the current process; the page fault is treated as an interrupt; the page reference is checked for legality and for presence on the disk; the disk request accounts for seek time and latency time; and while waiting, the CPU may be allocated to some other user — if the frame gets taken in the meantime, another interrupt is received, and after the I/O completes the registers are restored. This continues until a frame is present in memory and allocated to the page.
Two things matter for correctness: how to restart after a page fault, and how the instruction time is fetched during a page fault versus how data is fetched. An instruction that references several pages can fault partway through; the whole instruction must be restarted from its beginning, so the CPU must remember exactly where the faulting instruction started.
Real-world: the secondary storage used for this kind of paging is always known as the swap device — the swap space of a real system (a swap partition or swap file). Modern systems keep the swap on fast storage, but the operating system still works hard to keep the fault rate low, because every fault is a disk round trip.
13.3.4 Effective Access Time
To measure the performance of demand paging we use the page fault rate , which lies between 0 and 1. If , there is no page fault; if , every reference faults. The effective access time (EAT) combines the two cases: with probability the page is in memory and costs one memory access, and with probability we pay the page fault service time:
where is the memory access time and is the page fault service time — the time to bring the missing page from the disk. The formula is an expected value: each reference pays the cheap memory access most of the time, and occasionally pays the expensive disk service instead.
Worked example — the 200 ns / 8 ms system.
Given: memory access time nanoseconds; average page fault service time milliseconds; 1 out of 1000 accesses causes a page fault, so .
Units must match, so the 200 nanoseconds are converted into milliseconds: 200 ns ms. Substituting:
The answer is about 8.2 microseconds (0.0082 ms = 8.2 µs). The standard computation in the reference gives the same value, 8.2 µs; the arithmetic is identical whether the unit is called milliseconds or microseconds — only the label differs. The right label is microseconds, because 0.0082 ms is 8.2 µs.
Sense-check: with no faults at all, EAT would be 0.0002 ms. One fault per thousand references pushes EAT to 0.0082 ms — roughly 40 times slower. The lesson is structural: a tiny page fault rate like 1 in 1000 still swamps the whole effective access time, because the fault service time is tens of thousands of times larger than a normal access.
Scope — what the model assumes:
- stays small; the formula is a weighted average and says nothing about what happens when faults cluster.
- is dominated by disk service (seek + latency + transfer) plus interrupt handling and restart — about 8 ms on a classic hard disk. Queueing delays at the disk device add to this and are not in the formula.
- The takeaway holds regardless: the fault rate must stay tiny. The reference shows that to keep the slowdown below 10%, must stay under about 0.0000025 — fewer than one fault per 400,000 accesses.
Recap + bridge. Virtual memory runs processes larger than physical memory by keeping only active pages resident; demand paging brings pages in on first use, a page fault costs a full disk round trip, and even a 0.1% fault rate dominates the effective access time. When every frame is full and a new page is needed, something must be evicted — which brings us to page replacement algorithms.
13.4 Page Replacement Algorithms
Hook — who gets evicted? Every frame is full, and the process has just faulted on a page it needs right now. Some resident page has to leave. Choose badly and the machine spends its time swapping the same pages in and out; choose well and performance stays flat. The choice of which page to evict is the page replacement problem.
13.4.1 Why We Need Page Replacement
A page can be brought into memory only if a free frame exists. When all frames are occupied, the system must find a victim page: some page in memory that is not actually needed at present, or will not be needed for a while, is swapped out to secondary storage, and the page we need is brought into its frame. This happens when there is no free frame at all, and the performance then depends on how many page faults occur: the fewer the faults, the better the performance. We want an algorithm that always results in the minimum number of page faults. A bad policy can even cause the same page to be swapped out and swapped in many times.
The procedure for finding a free frame.
- Look on the disk: if a free frame exists, use it.
- If not, use a page replacement algorithm to select a victim frame.
- Return the victim to the disk.
- Update the page table and the frame table.
- Bring the required page into the now-free frame.
When there are no free frames, two page transfers take place — one to swap out the victim, one to bring in the required page — so the page fault service time increases.
To reduce that overhead we can keep one more bit, the modified bit (or dirty bit). The dirty bit records whether a page has been modified since it was loaded into memory. When a page is selected for replacement, the system checks its dirty bit: if the bit is clear, the page is identical to the copy on disk, so it can be dropped without any write-back — one transfer saved. Only pages with the dirty bit set (read-write pages that were actually written to) must be written out before the frame is reused. Clean, read-only pages such as binary code are never written back at all. This can cut the replacement I/O roughly in half.
So demand paging requires two algorithms together: the frame allocation algorithm, which allocates the free frames among the processes, and the page replacement algorithm, which decides which pages are to be replaced. They are different jobs, and we always want the one with the lowest page fault rate. Evaluation is done by feeding a given reference string — the sequence of pages a process references — through the algorithm and counting the page faults.
Common pitfalls
- Thinking replacement happens on every reference: it happens only on a page fault and only when no free frame exists.
- Confusing frame allocation with page replacement: allocation decides how many frames each process gets; replacement decides which page inside a full frame set leaves.
- Forgetting the dirty bit: assuming every eviction costs a write-back. Clean pages are dropped for free.
- Judging an algorithm by its first few faults: every algorithm pays the same "cold start" faults when the frames fill for the first time — the difference shows up in the faults that follow.
13.4.2 FIFO and Belady's Anomaly
The first page replacement algorithm is first in, first out (FIFO): the page that came into memory first is the one chosen for replacement. It is the simplest scheme — a queue: new pages enter at the tail, and the victim is whatever sits at the head. Its cost is one pointer per reference and no search at all.
Worked example — FIFO on a 12-reference string with three frames.
Reference string: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. Three frames are available.
- 1, 2, 3 are loaded into the three free frames — three page faults. Memory: 1, 2, 3.
- 4 arrives; no free frame. The page that came first is 1, so 1 is swapped out and 4 takes its place — four page faults. Memory: 4, 2, 3.
- 1 is referenced again but is not in memory; of the pages 4, 2, 3 the one that came first is 2, so 2 is the victim and 1 returns — five page faults. Memory: 4, 1, 3.
- 2 is referenced; it is not in memory. The page that came first is now 3, so 3 is the victim and 2 returns — six page faults. Memory: 4, 1, 2.
- 5 arrives; no free frame. The page that came first is 4, so 4 is removed and 5 is placed — seven page faults. Memory: 5, 1, 2.
- 1 is referenced: already present, no fault. 2 is referenced: present, no fault.
- 3 is referenced; not in memory. The victim is 1, which came first, giving memory 5, 3, 2 — eight page faults.
- 4 is referenced; not in memory. The victim is 2, the one that came first, giving memory 5, 3, 4 — nine page faults.
- 5 is referenced: present, no fault.
Total: 9 page faults with three frames.
Sense-check: at every step the evicted page is the one with the longest residence time — the queue head. The hit references (1, 2, 5) cause no queue movement and no faults.
Now suppose four frames are used instead of three, and the same pages are placed in the same manner: the number of page faults rises to 10. That is surprising: adding a frame made the algorithm perform worse. More frames leading to more page faults is Belady's anomaly, named for the person who showed it. The graph of frames versus page faults climbs instead of falling; you can take a reference string and run the algorithm yourself to see the same shape.
Visually, plot the number of frames on the horizontal axis and the number of page faults on the vertical axis. For most algorithms the curve falls as frames increase; for FIFO on this string it dips to 9 faults at three frames and then rises to 10 at four — a bump in the middle of a curve that should be falling. That bump is Belady's anomaly in the shape of a graph.
When to pick FIFO — and its cost. FIFO is easy to understand and cheap to run, but its performance is not always good. The page it evicts may be an initialization module used long ago and never needed again — fine — or it may be a heavily used variable that is in constant use — a disaster, because that page faults back almost immediately. A bad replacement choice never causes incorrect execution, only extra faults and slower execution. And because FIFO can suffer Belady's anomaly, it is never a guaranteed-safe choice.
13.4.3 Optimal Replacement
Optimal replacement says: replace the page that will not be used for the longest period of time. It thinks futuristic — it looks at the future and asks which page will not be needed for the longest time, picks that one as the victim, and replaces it.
Worked example — optimal on the same string with four frames.
Reference string: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. Four frames are available.
- 1, 2, 3, 4 are loaded — four faults.
- 1 and 2 are hits.
- 5 arrives; among 1, 2, 3, 4 the next uses are 1 (position 8), 2 (position 9), 3 (position 10), and 4 (position 11) — page 4 will not be used for the longest time, so 4 is replaced — five faults.
- 1, 2, 3 are hits.
- 4 arrives; of the pages now in memory, 1, 2, and 3 will never be referenced again, while 5 is referenced at the very end. The victim must be one of the never-again pages (say 3) — six faults.
- 5 is a hit.
Total: 6 page faults, against FIFO's 10 with the same four frames.
Sense-check on the last choice: page 5 must stay in memory, because the string ends with a reference to it. Evicting 5 instead of a never-again page would add one more fault and break the count — the lecture's total of 6 faults and the final hit on 5 both require removing a page that is never used again.
The catch: the algorithm needs future knowledge of the reference string — which page we may need, and which page will not be used. In real systems that knowledge is not available, which is the problem with this algorithm; it serves as the ideal that other algorithms are measured against. No algorithm can beat optimal on a given reference string with a fixed number of frames, so it is the yardstick: if a new algorithm stays within a few percent of optimal, it is doing well.
Worked example — optimal on the longer string with three frames.
Reference string: 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1. Three frames are available.
- 7, 0, 1 are loaded into the three frames — three faults.
- 2 arrives; the next uses are 7 (position 18), 0 (position 5), and 1 (position 14). Page 7 will not be used for the longest time, so 7 is the victim and 2 takes its place — four faults. Memory: 2, 0, 1.
- 0 is a hit.
- 3 arrives; the next uses are 0 (position 7), 2 (position 9), and 1 (position 14). Page 1 is the farthest, so 1 is the victim and 3 takes its place — five faults. Memory: 2, 0, 3.
- 0 is a hit.
- 4 arrives; the next uses are 2 (position 9), 0 (position 11), and 3 (position 10). Page 0 is farthest, so 0 is the victim and 4 takes its place — six faults. Memory: 2, 4, 3.
- 2 is a hit, 3 is a hit.
- 0 arrives; page 4 is never used again, so 4 is the victim and 0 returns — seven faults. Memory: 2, 0, 3.
- 3 is a hit, 2 is a hit.
- 1 arrives; page 3 is never needed again, so 3 is the victim and 1 takes its place — eight faults. Memory: 2, 0, 1.
- 2, 0, 1 are hits.
- 7 arrives; page 2 is never used again, so 2 is the victim and 7 returns — nine faults. Memory: 7, 0, 1.
- 0 and 1 are hits.
Total: 9 page faults, and the pattern shows the rule in action: at each replacement, look ahead at the reference string and sacrifice the page whose next use is farthest away. The reference reports 15 faults for FIFO on this same string, so optimal is nearly twice as good here.
Sense-check: every victim chosen is a page whose next use is at or after every other resident page's next use — including the three never-again pages (4, 3, 2) that are sacrificed when they can no longer serve the process.
13.4.4 LRU and Its Implementations
Least recently used (LRU) works from the past instead of the future: the page not used for the longest period of time so far is selected as the victim. The name says it — take out the one that has been idle longest. LRU is optimal looking backward: if the recent past is a good predictor of the near future, the page that was least useful recently is the page least likely to be needed next.
Worked example — LRU on the same string with four frames.
Reference string: 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5. Four frames are available.
- 1, 2, 3, 4 are loaded — four faults.
- 1 and 2 are hits.
- 5 arrives; the least recently used page is 3, so 3 is the victim and 5 takes its place — five faults. Memory: 1, 2, 5, 4.
- 1 and 2 are hits.
- 3 arrives; the least recently used page is 4, so 4 is the victim and 3 takes its place — six faults. Memory: 1, 2, 5, 3.
- 4 arrives; of 1, 2, 3, 5 the most recently used is 3 and the least recently used is 5, so 5 is the victim and 4 takes its place — seven faults. Memory: 1, 2, 4, 3.
- 5 arrives; 2, 3, 4 were recently used, and the least recently used is 1, so 1 is the victim and 5 takes its place — eight faults. Memory: 5, 2, 4, 3.
Total: 8 page faults — better than FIFO's 10 with the same four frames, worse than optimal's 6, exactly as expected: LRU approximates optimal from the past instead of the future.
Sense-check: after every hit, the referenced page becomes the most recently used; at every fault, the victim is the page with the longest idle time in the current frame set.
LRU can be implemented in several ways. With a counter (a clock): each page table entry gets a counter, and when a page is referenced the current clock value is copied into its counter; when a victim must be chosen, look at the counters and pick the page with the oldest value — the counter says when that page was last used. With a stack of page numbers: the stack keeps the pages ordered by recency of use, with the least recently used page at the bottom; when a page is referenced it is moved to the top, which requires double pointers and pointer updates; the victim is simply the page at the bottom, the one that came first and was not used recently. Or with a reference bit: each page carries a bit, initially zero; whenever a page is referenced the bit is set to one; when a victim is needed, pages whose bit is zero are candidates, and a page with the bit set to one is not considered.
The cost of true LRU is real: the counters or the stack must be updated on every memory reference. Doing that in software would slow every reference by a factor of about ten, so true LRU needs hardware support; systems without that support fall back to reference-bit approximations such as the second chance algorithm below.
When to pick LRU. LRU is the practical stand-in for optimal: it cannot be beaten without future knowledge, and on real workloads the recent past predicts the near future well. The price is the per-reference bookkeeping — counters need a search over the table, and the stack needs up to six pointer updates per reference. For systems without the hardware, use the reference-bit approximations instead.
13.4.5 Second Chance and Counting Algorithms
The reference bit idea grows into the second chance algorithm. When a victim must be selected, walk through the pages and look at each reference bit. If the bit is zero, replace that page. If the bit is one, give the page a second chance: clear the bit to zero and move on to the next page. A recently referenced page survives one more round; only if it stays untouched will it be replaced on a later pass.
The standard implementation is a circular queue with a pointer — the clock algorithm: the pointer advances until it finds a page with a zero reference bit, clearing the bits of every page it passes. If all bits are set, the pointer makes a full circuit, clearing every bit and giving every page a second chance — and the algorithm then degenerates into plain FIFO. A further refinement pairs the reference bit with the modify bit, preferring clean pages (0,0) over modified ones, but the core idea stays the same: one round of grace for recently used pages.
Beyond LRU and its variations there are counting algorithms. Keep a count of how many references have been made to each page. LFU (least frequently used) always replaces the page with the smallest count; MFU (most frequently used) replaces the page with the largest count. If the count is very small, the page is least frequently used; a large count means most frequently used. These are not common algorithms in practice: LFU keeps pages that were heavily used long ago but are now dead weight, and MFU rests on the shaky argument that a small count means a page was just brought in and has yet to prove itself.
13.4.6 Choosing a Replacement Algorithm
Two properties matter when comparing algorithms. FIFO can exhibit Belady's anomaly — more frames, more faults. Optimal and LRU do not exhibit the anomaly: with either of them, increasing the number of free frames never increases the page faults. That is their beauty. The reason is structural: optimal and LRU are stack algorithms — the set of pages they keep with frames is always a subset of the set they keep with frames — so more frames only ever add pages, never push useful ones out. FIFO has no such property.
| Algorithm | Looks at | Belady's anomaly | Feasible in practice? | Faults on 1,2,3,4,1,2,5,1,2,3,4,5 |
|---|---|---|---|---|
| FIFO | arrival time (past) | Yes | Yes — a simple queue | 9 (3 frames), 10 (4 frames) |
| Optimal | next use (future) | No | No — needs future knowledge; used as the ideal | 6 (4 frames) |
| LRU | last use (past) | No | Yes, with hardware; otherwise approximated | 8 (4 frames) |
Among all the algorithms, optimal is far better — but it needs the future, so LRU (with past knowledge) is the practical stand-in. You can verify this yourself: take the example reference strings, assume three frames in one run and five frames in another, work out the faults for each algorithm, and make a comparison — the counts confirm both the ordering and the anomaly immunity.
Exam note: page replacement algorithms are very important. Expect to work a reference string by hand for FIFO, optimal, and LRU, and to count page faults — and to know which algorithms are immune to Belady's anomaly. Memorize the shape of the rule for each: FIFO evicts the oldest arrival, optimal evicts the page with the farthest next use, LRU evicts the page idle the longest.
Recap + bridge. Page replacement picks a victim when no free frame exists: FIFO (oldest arrival, suffers Belady's anomaly), optimal (farthest next use, needs the future, the ideal), LRU (idle longest, the practical stand-in), with second chance and LFU/MFU as cheaper or counting variants. Frames are allocated and pages are replaced — but when a process has too few frames, even the best replacement policy cannot help. That failure mode is thrashing, the next topic.
13.5 Segmentation
Hook — memory that respects the program. Paging shreds a program into equal chunks, but the programmer thinks of a program as meaningful parts: a main program, procedures, methods, variables. What if memory management could respect those parts instead of cutting across them? Segmentation is exactly that scheme.
13.5.1 The User's View of Memory
Segmentation is another memory management scheme, and it supports the user view of memory: as a user, a program is always a collection of segments. A segment can be a main program, a procedure, a method, a small module — whatever you consider — and even variables or a block of information count as a segment. The compiler is the one that generates these segments, and the loader assigns a number to each and every segment. Each segment can have its own size, so variable sizes are fine; there is no required order in which segments are placed, and none is needed.
Because the whole logical address space is built from these segments, an address must always be specified in two parts: the segment number (or name) followed by the segment offset. Together they form the logical address. To see the logical view, address it with the segment number and the offset.
An everyday picture: a multi-drawer cabinet. Each drawer is a segment — drawers hold different amounts and are labeled with different contents; the address of any item is (drawer number, position inside the drawer). The analogy breaks in one place: the drawers in the cabinet sit side by side, while segments in memory can be scattered anywhere, and their sizes are set by the compiler, not by the cabinet maker.
The comparison with paging shows what segmentation buys and what it costs:
| Dimension | Paging | Segmentation |
|---|---|---|
| Unit of division | fixed-size pages (equal blocks) | variable-size segments (program parts) |
| User's view | hidden — pages are an artifact of hardware | natural — segments are program structure |
| Logical address | page number + offset | segment number + offset |
| Table entry | frame number (+ bits) | base + limit |
| Fragmentation | internal (waste inside pages) | external (gaps between segments) |
| Sharing code | harder (page boundaries split modules) | easier (a segment is a whole module) |
When to pick which: paging for simplicity and no external fragmentation; segmentation when the program's structure should drive memory layout and sharing matters.
13.5.2 The Segment Table and Address Translation
Where paging had a page table, segmentation has a segment table. The segment table has two entries per segment: the base and the limit. The base is the starting physical address where the segment is present in memory; the limit is the length of each segment. Two registers maintain these: the segment table base register (STBR) points to the location of the segment table in memory, and the segment table length register (STLR) specifies how many segments are in memory. A segment number is legal only when it is less than the value in the length register; the length register sets the legal range for segment numbers.
Translation in four steps, with the legality rule.
- Split the logical address into segment number and offset .
- Check the segment number against the STLR: is legal only if STLR.
- Look up segment in the segment table; read its base and its limit.
- Check the offset against the limit. If the offset is within the limit, the address is valid and the physical address is:
If the offset is not within the limit, the reference is an addressing error and is rejected — the process has tried to reach past the end of its own segment.
The base and limit pair is a protection mechanism: a process can only ever touch memory inside its own segments, and any address beyond a segment's limit is stopped at the table, before it reaches memory. The offset is a distance from the segment's start, so must hold.
Scope — where segmentation applies and breaks.
- Segments are variable-sized, so memory is allocated in variable-sized blocks — the same scheme as dynamic partitioning, and it suffers the same external fragmentation: small free gaps appear between segments, too small to be useful.
- The segment table sits in memory and is indexed by the segment number; the STBR and STLR give the hardware everything it needs to find the table and check legality.
- Sharing works naturally: two processes can point at the same segment base, and read-only, reentrant modules (libraries) are shared without copying.
13.5.3 Worked Example: Checking Legal Segment Addresses
The lecture works the classic five-address example; the segment table it is taken from (the textbook exercise) is the one below.
Worked example — five logical addresses checked against the segment table.
Segment table:
| Segment | Base | Limit |
|---|---|---|
| 0 | 1400 | 1000 |
| 1 | 6300 | 400 |
| 2 | 4300 | 400 |
| 3 | 3200 | 1100 |
| 4 | 4700 | 1000 |
For each logical address (segment, offset), check offset < limit first, then add the base:
- (0, 430): the limit for segment 0 is 1000, and 430 is less than 1000, so the offset is valid. The physical address is the base plus the offset: .
- (1, 10): 10 is less than the limit 400, so it is valid; the physical address is .
- (2, 500): the limit for segment 2 is 400, and 500 is not less than it, so this is not a legal reference — a trap is made; it is an addressing error.
- (3, 400): 400 is less than 1100, the limit for segment 3, so it is valid; the physical address is .
- (4, 112): 112 is less than 1000, the limit for segment 4, so it is valid; the physical address is .
Sense-check: every computed address lies inside its segment's range — 1830 in [1400, 2400), 6310 in [6300, 6700), 3600 in [3200, 4300), 4812 in [4700, 5700) — and the only rejected address is the one whose offset exceeds its segment's limit.
One note on the numbers: the limits spoken in the lecture were partly garbled (segments 0–4 were read at different points as roughly 600, 40, 100, 580, and 96). The table above is the canonical one from the textbook exercise that these exact addresses come from. The verdicts agree with the lecture for (0, 430), (1, 10), (2, 500), and (3, 400) — and for (4, 112) the lecture's garbled limit of 96 would reject the reference, while the textbook limit of 1000 accepts it at 4812. Both versions share the identical rule: check offset < limit before adding the base, and an address that fails the check raises a trap.
The rule to carry away: always verify offset < limit first; only a valid offset can be added to the base to form the physical address.
Recap + bridge. Segmentation lays memory out as variable-size program parts — segment number + offset addresses, a segment table of base and limit pairs guarded by the STBR and STLR, and a legality check that traps any offset beyond the limit. It trades paging's fixed-size simplicity for a memory layout that matches the program — at the cost of external fragmentation. With paging and segmentation in hand, the next question is what happens when a process has too few frames to work with: thrashing.
13.6 Thrashing
Hook — more memory, slower machine? Add another process to memory and, up to a point, the CPU gets busier. Past that point the machine suddenly gets slower, not faster. The operating system is no longer executing programs — it is busy swapping pages in and out for the same program, forever. That condition has a name: thrashing.
13.6.1 What Thrashing Is
If a process does not have enough pages, its page fault rate stays high. Imagine a memory holding some pages, but the process keeps referring to pages that are not in memory at all: every page reference is a fault, every fault forces a replacement of an existing frame, and then the next reference faults again. Each and every reference requires swapping out a page and bringing in another, so most of the time the system spends itself on replacement instead of execution. That condition — a process busy always swapping pages in and out — is thrashing, and it must not occur. Its cost is a direct drop in CPU utilization: the CPU is there and ready to execute pages, but the pages are never there when needed.
An everyday picture: a chef whose ingredient bins are too small for the dish being cooked. Every dish forces a trip to the cold storage to swap ingredients in and out of the bins; the chef spends the evening walking, not cooking. The mapping: the chef is the CPU, the bins are the frames, and cold storage is the swap device. The break point: the chef could simply use bigger bins, but a process's reference pattern is fixed by the program — the only fix is giving the process enough frames for the pages it is actually using.
Common pitfalls
- Blaming the page replacement algorithm for thrashing: thrashing is a frame-allocation failure — the process has too few frames for its current working set, so no replacement policy can help.
- Thinking thrashing is merely "many page faults": it is the cycle — a fault, a replacement, the next reference faulting again — that spends the system on swapping instead of executing.
- Expecting utilization to keep rising as processes are added: past the thrashing point, utilization falls.
13.6.2 Degree of Multiprogramming and CPU Utilization
The degree of multiprogramming and CPU utilization are directly proportional up to a point. As more processes are placed in memory, the CPU stays busy with some work and utilization rises. But beyond a certain point, the number of pages present in memory becomes too few, thrashing begins, and utilization falls instead of rising. The curve goes up, peaks, and turns down; the peak is the thrashing point. Increasing the degree of multiprogramming past that point is counterproductive — the CPU has less to do, not more.
Visually, plot the degree of multiprogramming on the horizontal axis and CPU utilization on the vertical axis. The curve climbs steeply at first as more processes keep the CPU busy, flattens as memory fills, and then falls away on the right as thrashing takes over. The landmark is the peak: the best degree of multiprogramming sits at the top of the curve, where utilization is highest and no process is starved of frames.
13.6.3 Locality and the Working Set Model
Why does thrashing happen? The explanation comes from the locality model. A locality is the set of pages that are actively used together at a time. The process moves through localities: some pages are referenced together, then the process migrates to another group, and localities may even overlap. Thrashing occurs when the total size of the working locality is larger than the total memory size — then every time one page is brought in, another must be swapped out, and the faulting never stops.
Demand paging can be made to work with the locality model. One way to limit thrashing is local replacement — the priority replacement algorithm built on the working set model. With the working set model, keep a window of references: the pages referenced within the current window are the working set, and they get priority — they will not be swapped out. Pages referenced only outside the window (4, 5, 6, whatever is not in the window) are the ones considered for replacement. The window slides as references accumulate, so the protected set tracks where the process currently is.
The working set idea formalizes cleanly: pick a window size (say, the last references); the working set at any moment is the set of distinct pages referenced inside that window. Each process then has a working set size , and the total frame demand is
If the total demand exceeds the number of available frames , some process cannot keep its working set resident — and thrashing follows. The fix is to give each process as many frames as its working set needs, and to suspend a process (swap it out entirely) when the sum of working set sizes exceeds memory. Choosing matters: too small a window misses part of the locality, too large a window overlaps several localities, and an infinite window covers every page the process ever touched.
Scope — the model's assumption. The working set model leans on locality: programs really do reference pages in clusters (a function call pulls in its instructions, its locals, and some globals together; leaving the function drops them from the active set). If references were random rather than patterned, the working set would be the whole program, and no window would help — which is why the model works for real code and fails for random-access workloads.
The course textbook covers the local and priority replacement methods in detail; for the concept itself, the summary above is enough — and the page replacement algorithms, together with the paging problems, are the important material of this topic.
Real-world: the working set idea is embedded in real systems — Windows tracks a per-process working set with minimum and maximum sizes and trims pages when memory tightens, and Linux approximates the same idea with reference-bit clocks and page-fault-frequency control. Servers and databases tune these knobs so that interactive processes keep their hot pages resident while batch work is suspended.
Recap + bridge. Thrashing is a process spending its time swapping pages instead of executing, caused by giving it fewer frames than its current locality needs; CPU utilization peaks at the thrashing point as processes are added. The working set model protects the pages referenced inside a sliding window, keeping each process's demand within the frames available . That closes the memory story — paging, virtual memory, replacement, segmentation, and the failure mode that binds them together.
13.7 OS Simulator: Running the Assignment Simulations
13.7.1 Q&A: How to Run the Simulations
One of the assignment problems (question 15) asks for six programs to be run, and a student raised a doubt about it. The resolution is a straight procedure: the simulator does the work once each program is loaded, and the skill being tested is reading the snapshots and the process view afterward.
Q: I am facing difficulty with question 15 of the assignment — it asks me to work with six programs. A: Take each of the six programs separately. Compile every program on its own, then load it into memory. Copy and paste the program into the OS simulator, select it, compile it, and load it — the simulator picks it up automatically. Then follow the steps: if you are doing round robin scheduling, make sure round robin is selected, execute it, take a snapshot, suspend the execution for some time, go to the process view, and check the resources there. Take the snapshots you need and explain what you see, one step after another, following the questions given.
The procedure, step by step:
- Compile each of the six programs on its own, one at a time.
- Load the compiled program into the simulator — copy and paste it, select it, compile it in the simulator, and load it; the simulator picks it up automatically.
- Select the scheduling algorithm — for round robin, make sure round robin is selected before executing.
- Execute the program.
- Take a snapshot of the run.
- Suspend the execution for some time.
- Open the process view and check the resources shown there.
- Explain what you see, one step after another, and use the snapshots as evidence, following the questions given.
13.7.2 Study Resources
Reference PDFs were shared for each topic — deadlock, synchronization, threads, and scheduling — and the questions for the assignment are there too. Whatever is in those reference PDFs is the overall view to follow. The OS simulator itself is the tool to practice on: run the programs, take snapshots, suspend execution, and inspect the process view and the resources. The course textbook covers the underlying policies — scheduling, synchronization, and deadlock — in depth, so use it to understand the why behind each snapshot the simulator shows.
Exam Guidance Summary
- Page replacement algorithms are very important. Be ready to work reference strings by hand for FIFO, optimal, and LRU, and to count page faults. Know Belady's anomaly: FIFO can produce more faults with more frames, while optimal and LRU cannot. Practice on the lecture strings — 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5 (9, 10, 6, and 8 faults for FIFO-3, FIFO-4, optimal-4, and LRU-4) and 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1 (9 faults for optimal-3).
- Paging numerical problems are important. The five-question pattern (bits in the logical address, bytes in a frame, bits that specify the frame, page table entries, bits per entry) is core material; work through the practice question with the given answers and the shared practice examples. Remember the chain: address space → bits → frames → entries → bits per entry.
- The important topics of this material are paging and the problems worked for it, plus the page replacement algorithms; solve the example problems on your own and check your answers. Also review the EAT formula from Section 13.3 (a 0.1% fault rate still dominates the effective access time) and the offset < limit rule from Section 13.5, since both are worked-example favorites.
- Assignment work: use the OS simulator — compile each program separately, load it, select the scheduling algorithm (round robin, for example), execute, take snapshots, suspend, and inspect resources in the process view — and support the results with explanations.
Key Industry Applications
- Real-world: the TLB is the hardware cache inside the processor that makes address translation fast; without it every memory access would cost two trips. Every modern CPU — x86, ARM, RISC-V — ships a TLB, and designs such as x86 huge pages (2 MB or 1 GB) exist largely to widen the TLB's reach.
- Real-world: virtual memory is how modern operating systems run programs that are bigger than physical memory and how they raise the degree of multiprogramming — every desktop browser, database server, and container runtime depends on it.
- Real-world: the secondary storage used for paging is known as the swap device — the swap space of a real system (a swap partition or swap file on Linux, the page file on Windows).
- Real-world: the OS simulator is a practical tool for exercising scheduling and resource-management policies end to end, letting students watch round robin, snapshots, and the process view in action before meeting the policies on a real system.
OS Lecture 13 notes · Memory Management: Paging, Virtual Memory, Page Replacement, Segmentation, and Thrashing
Sections Breakdown
Pages and frames, page table address translation, TLB hardware, and page size trade-offs.
The five-question paging problem: logical address bits, frame bytes, physical frame bits, page table entries, and bits per entry.
Virtual memory, demand paging with the lazy swapper, the page fault sequence, and effective access time.
FIFO, optimal, and LRU replacement with worked reference strings, Belady's anomaly, second chance, and counting algorithms.
The user's view of memory, the segment table with base and limit, and legal address translation.
Thrashing as a frame-allocation failure, multiprogramming versus CPU utilization, and the working set model.
Running the assignment simulations in the OS simulator: compile, load, execute, snapshot, suspend, and inspect the process view.
Exam strategy and priorities for page replacement, paging numerical problems, and assignment work.
Real-world connections: the TLB, virtual memory, the swap device, and the OS simulator.
Exam Revision Notes
Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.
Paging Review: Pages, Frames, and the Page Table
Must-know: A logical address splits into a page number and an offset; the physical address is (frame number x frame size) + offset; page numbers name logical pages, frame numbers name physical slots, and the frame size always equals the page size.
⚠️ Top pitfall: Confusing page numbers (logical address space) with frame numbers (physical memory), or using the offset alone as the physical address without adding the frame base.
Self-check: Page 2 maps to frame 7 in a 4-byte-page system: where does page 2 start, and which addresses does it cover?
Connects to: 13.2, 13.3, 13.4
Worked Problem: How Many Bits in a Paging System
Must-know: Bits in the logical address = log2(page size x number of pages) = 26 here; frames = physical memory / frame size = 2^22; page table entries = number of pages = 2^16; bits per entry = frame-number bits = 22. Address space (2^26 bytes) is not the address (26 bits).
⚠️ Top pitfall: Saying the logical address space is 26 bits when it is 2^26 bytes; the address itself is the 26-bit value pointing inside it.
Self-check: If the page size were 2^12 and physical memory 2^36 bytes, how many frames fit and how many bits does the frame number use?
Connects to: 13.1, 13.3
Virtual Memory and Demand Paging
Must-know: Virtual memory runs processes not fully in memory; the valid/invalid bit flags missing pages; a page fault traps to the OS, reads the page from the swap device, updates the table, and restarts the instruction. EAT = (1-p)*T_memory + p*T_fault: with 200 ns access, 8 ms fault service and p = 0.001, EAT is about 8.2 microseconds.
⚠️ Top pitfall: Mislabelling the EAT result as 8.2 milliseconds; 0.0082 ms is 8.2 microseconds. Also reading 'invalid' as 'illegal' — invalid means not present in memory.
Self-check: What does the valid/invalid bit say when a page is in memory, and what event occurs when translation hits an invalid entry?
Connects to: 13.1, 13.4, 13.6
Page Replacement Algorithms
Must-know: FIFO evicts the oldest arrival and can show Belady's anomaly (9 faults at 3 frames, 10 at 4 on 1,2,3,4,1,2,5,1,2,3,4,5); optimal evicts the page not used for the longest time (6 faults) but needs future knowledge; LRU evicts the page idle longest (8 faults) and, like optimal, never shows Belady's anomaly.
⚠️ Top pitfall: Evicting a page that is referenced again soon — e.g., in optimal replacement evicting page 5 on the lecture string, which is referenced at the very end; the victim must be a page whose next use is farthest away.
Self-check: On the string 1,2,3,4,1,2,5,1,2,3,4,5 with four frames, why does optimal give 6 faults while FIFO gives 10?
Connects to: 13.1, 13.3, 13.6
Segmentation
Must-know: A logical address is (segment number, offset); the segment table gives base and limit; the offset must be strictly less than the limit or the reference traps; otherwise physical address = base + offset.
⚠️ Top pitfall: Adding the base before checking the offset against the limit — the check comes first, and an illegal offset traps; also reading the limit as an end address instead of a length.
Self-check: Segment 3 has base 3200 and limit 1100: is (3, 400) legal, and what is the physical address?
Connects to: 13.1, 13.2
Thrashing
Must-know: Thrashing = a process whose page fault rate stays high because it has too few frames, so every reference forces a swap; CPU utilization peaks at the thrashing point of the multiprogramming degree. The working set model protects pages referenced inside the current window and demands D = sum of working set sizes <= frames m.
⚠️ Top pitfall: Blaming the page replacement algorithm for thrashing — it is a frame allocation failure; also expecting utilization to keep rising with more processes past the peak.
Self-check: What happens to CPU utilization when the degree of multiprogramming is pushed past the thrashing point, and why?
Connects to: 13.3, 13.4
OS Simulator: Running the Assignment Simulations
Must-know: Simulator workflow for assignment question 15: compile each program separately, load it into the OS simulator, select the scheduling algorithm (e.g., round robin), execute, snapshot, suspend, and inspect the process view and resources, explaining each step with the snapshots.
⚠️ Top pitfall: Running all six programs at once instead of taking each program separately — compile, load, execute, and snapshot one at a time.
Self-check: After suspending a round robin run in the simulator, where do you look to see each program's resources?
Exam Guidance Summary
Must-know: For the exam: hand-trace FIFO, optimal, and LRU on reference strings and count page faults; know that FIFO can exhibit Belady's anomaly while optimal and LRU cannot; work the five-question paging pattern (bits, frame bytes, frame bits, entries, bits per entry).
⚠️ Top pitfall: Not practicing reference-string traces by hand — the exam expects hand-worked faults, and the chain questions (bits to entries) build on each other.
Self-check: Which of FIFO, optimal, and LRU never show more faults when frames increase, and why?
Connects to: 13.2, 13.4
Key Industry Applications
Must-know: TLB = the processor's translation cache (every memory access otherwise costs two trips); virtual memory runs programs bigger than RAM; the swap device is a real system's swap space.
Self-check: Why would an x86 system use 2 MB huge pages?
Connects to: 13.1, 13.3
Was this lecture useful?
BitsNotes AI Assistant
Subject Notes AssistantConfigure AI Chat
Choose how to access the chatbotSigned in as
Powered by BitsNotes — 20 messages per day. No API key needed. Want unlimited access? Use "Bring Your Own Key" mode.
Sign in to use AI Chat
Get 20 free AI messages per day to ask questions about your lecture notes. Sign in with Google or GitHub — it takes 5 seconds.
Sign In to BitsNotesSwitch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.