Loading learning content...
Imagine trying to seat guests at a wedding reception where every family must sit together at contiguous tables. If the Johnson family of six arrives after you've already seated several smaller families, you might find that despite having ten empty chairs scattered throughout the hall, there's no group of six adjacent chairs available. This is exactly the problem operating systems faced with contiguous memory allocation—and paging is the elegant solution that revolutionized memory management.
Paging is fundamentally about breaking the assumption of contiguity. Rather than requiring a process's memory to occupy a single continuous block of physical memory, paging allows the operating system to scatter a process's memory across any available physical locations while maintaining the illusion of contiguous memory to the process itself.
By the end of this page, you will understand the fundamental abstraction at the heart of paging: how logical memory is divided into fixed-size pages, how physical memory is divided into fixed-size frames, and how this simple yet powerful decomposition enables the operating system to manage memory with unprecedented flexibility and efficiency.
Before we can appreciate paging, we must understand the fundamental limitations it addresses. In contiguous memory allocation, each process must occupy a single, unbroken block of physical memory addresses. This requirement creates several severe problems:
External Fragmentation: As processes are loaded and unloaded from memory, the available free space becomes fragmented into many small, non-contiguous holes. Even when the total free memory exceeds a process's requirements, the process cannot be loaded if no single contiguous block is large enough.
Compaction Overhead: The only solution to external fragmentation in contiguous systems is compaction—physically moving processes in memory to consolidate free space. This is extremely expensive because:
Rigid Allocation: Processes must declare their maximum memory requirements upfront, leading to either:
The root cause of these problems is a single, seemingly reasonable assumption: that a process's logical address space must map to a contiguous range of physical addresses. Paging eliminates this constraint entirely, providing a fundamental breakthrough in memory management.
Consider this scenario demonstrating external fragmentation:
Initial state: 128 KB total memory
| Process A (32KB) | Process B (24KB) | Process C (40KB) | Free (32KB) |
After Process B terminates:
| Process A (32KB) | Hole (24KB) | Process C (40KB) | Free (32KB) |
New process D needs 48KB:
- Total free memory: 24KB + 32KB = 56KB ✓
- Largest contiguous block: 32KB ✗
- Result: Process D cannot be loaded!
Despite having 56KB free—more than enough for Process D—the system cannot accommodate the request. This is the fundamental problem paging solves.
Paging introduces a beautifully simple abstraction that eliminates the contiguity problem:
This last point is the key insight: by standardizing the size of allocation units, we ensure that any free frame can hold any page. There's no need to find a block 'large enough'—all blocks are exactly the same size, and therefore all blocks are interchangeable.
| Concept | Pages | Frames |
|---|---|---|
| Domain | Logical (Virtual) Address Space | Physical Memory |
| Managed by | Viewed by the process | Managed by the OS |
| Numbering | Page numbers (0, 1, 2, ..., n-1) | Frame numbers (0, 1, 2, ..., m-1) |
| Contiguity | Logically contiguous to the process | Can be anywhere in physical memory |
| Size | Fixed (typically 4KB) | Same as page size |
| Count | Depends on process size | Depends on physical memory size |
The fundamental relationship:
A process sees its memory as a linear sequence of pages numbered 0, 1, 2, and so on. From the process's perspective, these pages are contiguous—page 1 immediately follows page 0 in the logical address space. However, in physical memory, page 0 might be in frame 47, page 1 in frame 12, and page 2 in frame 103. The operating system maintains a page table that records which frame holds each page, enabling transparent translation between the process's view (logical addresses) and reality (physical addresses).
Paging separates the programmer's view of memory (a continuous address space) from the physical reality (scattered frames). The process believes it has contiguous memory; the OS knows it's scattered across physical RAM. This illusion is maintained through hardware-assisted address translation on every memory access.
A page is a fixed-size block of contiguous logical addresses within a process's address space. Understanding pages requires understanding how logical addresses are structured in a paging system.
Logical Address Structure:
In a paging system, every logical address generated by the CPU is conceptually divided into two parts:
|<---- Page Number (p) ---->|<---- Page Offset (d) ---->|
The size of the page determines how many bits are used for each part. For a page size of 2^n bytes:
n bits of the address form the offsetLogical address: 0x00007A9C (31388 in decimal)Page number: 7, Offset: 0xA9C (2716)With 4KB pages, we need 12 bits for the offset (2^12 = 4096). In the address 0x00007A9C:
This address refers to byte 2716 within page 7 of the process's logical address space.
Page Characteristics:
Fixed Size: All pages within a system are exactly the same size. This uniformity is essential for the interchangeability that makes paging work.
Logical Entity: Pages exist in the logical address space. A process with a 64KB address space and 4KB pages has exactly 16 pages (numbered 0-15).
Internal Contiguity: Within a page, addresses are truly contiguous. Byte 0 of page 3 is followed by byte 1 of page 3, and so on.
Page Boundaries: Pages begin at addresses that are multiples of the page size. With 4KB pages, pages start at addresses 0x0000, 0x1000, 0x2000, etc.
Process-Specific Numbering: Page numbers are local to each process. Process A's page 5 and Process B's page 5 are completely unrelated.
A critical understanding: pages exist only in the logical address space. They're a way of thinking about and organizing the process's memory. The process doesn't 'contain' pages any more than a book 'contains' chapters—chapters are how we organize the content, just as pages are how the OS organizes memory.
A frame (also called a page frame or physical frame) is a fixed-size block of contiguous physical memory. Frames are the physical counterpart to logical pages—if pages are containers in a process's imagination, frames are actual containers in RAM.
Physical Address Structure:
Just as logical addresses decompose into page number and offset, physical addresses decompose into:
|<---- Frame Number (f) ---->|<---- Frame Offset (d) ---->|
Critical insight: Because pages and frames are the same size, the offset is identical in both the logical and physical addresses. Only the page/frame number changes during address translation.
| Aspect | Description |
|---|---|
| Frame Table | A global data structure tracking the status of every frame: whether it's free, allocated, and if allocated, to which process/page |
| Frame Allocation | When a process needs memory, the OS allocates available frames from anywhere in physical memory |
| Frame Deallocation | When a process terminates or releases memory, its frames return to the free pool |
| Frame Protection | The OS ensures processes can only access frames allocated to them |
| Frame Sharing | Multiple processes can share frames (e.g., for shared libraries) with proper protection |
The Frame Table:
The operating system maintains a system-wide frame table that tracks the state of every physical frame:
Frame Table:
┌───────┬────────────┬─────────────┬─────────────┐
│ Frame │ Status │ Process │ Page │
├───────┼────────────┼─────────────┼─────────────┤
│ 0 │ Reserved │ Kernel │ - │
│ 1 │ Reserved │ Kernel │ - │
│ 2 │ Allocated │ PID 201 │ Page 0 │
│ 3 │ Free │ - │ - │
│ 4 │ Allocated │ PID 105 │ Page 3 │
│ 5 │ Allocated │ PID 201 │ Page 2 │
│ 6 │ Free │ - │ - │
│ 7 │ Allocated │ PID 105 │ Page 0 │
│ ... │ ... │ ... │ ... │
└───────┴────────────┴─────────────┴─────────────┘
Notice how frames 2 and 5 belong to the same process (PID 201) but hold different pages (0 and 2). This illustrates the non-contiguous nature of paging: process 201's pages are scattered across frames 2 and 5, with frame 4 (belonging to a different process) in between.
Because all frames are the same size, any free frame can hold any page. This property completely eliminates external fragmentation—there's never a situation where you have 'enough memory but not in the right shape.' If you have N free frames, you can load any process that needs N or fewer pages.
The heart of paging is the mapping between pages and frames. This mapping is maintained in a structure called the page table, which exists for each process (we'll explore page tables in detail in the next module). For now, let's understand the concept of the mapping itself.
The Mapping Function:
Conceptually, the page table implements a function:
f(page_number) → frame_number
For a given process, if page 5 is stored in frame 27, the page table entry for page 5 contains the value 27. When the CPU accesses logical address X within page 5, the Memory Management Unit (MMU) uses the page table to translate this to the corresponding address within frame 27.
Key Properties of the Mapping:
One Process's View: Each process has its own page table, its own mapping. Process A's page 3 might map to frame 50, while Process B's page 3 maps to frame 12.
Dynamic Nature: The mapping can change. The OS might move a page to a different frame if needed (after updating the page table, of course).
Sparse Possibility: Not all page table entries need to be valid. A process might only use a small portion of its potential address space, with most pages marked as 'invalid' (not present in memory).
Offset Preservation: The offset within a page equals the offset within the corresponding frame. If you're accessing byte 500 of page 7, you'll access byte 500 of whatever frame holds page 7.
System: 4KB pages, 32-bit addresses. Process P has page 7 in frame 42. Logical address: 0x00007B00Physical address: 0x0002AB00Step 1: Decompose logical address
Step 2: Look up page 7 in page table
Step 3: Construct physical address
The frame number replaces the page number, offset stays the same.
Let's visualize how memory is divided into pages and frames, and how the mapping works in practice.
Physical Memory (Frames):
Physical Memory: 64KB (16 frames of 4KB each)
┌─────────────────┐ ← 0x0000
│ Frame 0 │ Kernel reserved
├─────────────────┤ ← 0x1000
│ Frame 1 │ Kernel reserved
├─────────────────┤ ← 0x2000
│ Frame 2 │ Process A, Page 0
├─────────────────┤ ← 0x3000
│ Frame 3 │ FREE
├─────────────────┤ ← 0x4000
│ Frame 4 │ Process B, Page 0
├─────────────────┤ ← 0x5000
│ Frame 5 │ Process A, Page 2
├─────────────────┤ ← 0x6000
│ Frame 6 │ Process B, Page 1
├─────────────────┤ ← 0x7000
│ Frame 7 │ FREE
├─────────────────┤ ← 0x8000
│ Frame 8 │ Process A, Page 1
├─────────────────┤ ← 0x9000
│ Frame 9 │ Process B, Page 2
├─────────────────┤ ← 0xA000
│ Frame 10 │ FREE
├─────────────────┤ ← 0xB000
│ Frame 11 │ Process A, Page 3
├─────────────────┤ ← 0xC000
│ Frame 12 │ FREE
├─────────────────┤ ← 0xD000
│ Frame 13 │ Process B, Page 3
├─────────────────┤ ← 0xE000
│ Frame 14 │ FREE
├─────────────────┤ ← 0xF000
│ Frame 15 │ FREE
└─────────────────┘ ← 0x10000
Process A's Page Table:
┌──────┬────────┐
│ Page │ Frame │
├──────┼────────┤
│ 0 │ 2 │
│ 1 │ 8 │
│ 2 │ 5 │
│ 3 │ 11 │
└──────┴────────┘
Process A sees:
But physically, pages are scattered across frames 2, 8, 5, and 11.
Process B's Page Table:
┌──────┬────────┐
│ Page │ Frame │
├──────┼────────┤
│ 0 │ 4 │
│ 1 │ 6 │
│ 2 │ 9 │
│ 3 │ 13 │
└──────┴────────┘
Process B sees:
Process B has the same logical view but different physical frames.
Both Process A and Process B believe they have nice, contiguous memory from 0x0000 to 0x3FFF. The operating system has given each a 16KB address space. But in physical reality, each process's memory is scattered across non-adjacent frames. This illusion is the fundamental power of paging.
Paging requires intimate cooperation between hardware and software. The Memory Management Unit (MMU), a hardware component usually integrated into the CPU, performs address translation for every memory access. This is critical because even a single machine instruction might generate multiple memory accesses, and software-based translation would be far too slow.
The MMU's Role:
This entire process must happen in hardware, transparently, on every single memory reference—millions or billions of times per second.
The Translation Process in Detail:
1. CPU executes instruction that references logical address LA
2. MMU receives LA
3. MMU splits LA into (page_number, offset)
4. MMU checks if (page_number, frame) is cached in TLB
- If TLB hit: Use cached frame number
- If TLB miss: Read page table entry from memory
5. MMU checks valid bit in page table entry
- If valid: Extract frame number
- If invalid: Raise page fault exception
6. MMU checks protection bits
- If access permitted: Continue
- If access denied: Raise protection fault exception
7. MMU combines frame_number with offset to form physical address PA
8. Physical address PA sent to memory controller
9. Memory returns/accepts data at that address
This entire sequence must complete in nanoseconds. The TLB is crucial—without it, every memory access would require two memory accesses (one to read the page table entry, one for the actual data), halving memory performance.
The history of paging is intertwined with hardware evolution. Architectures like x86, ARM, RISC-V, and others have dedicated silicon for address translation. Modern CPUs spend a significant portion of their transistor budget on MMU functionality, TLB caches, and page walk hardware. Paging isn't just a software concept—it's deeply embedded in processor architecture.
Paging was not invented in isolation—it emerged from decades of struggle with memory management limitations. Understanding this history illuminates why paging works the way it does.
The Evolution of Memory Management:
Bare Machine (1950s): Programs loaded at fixed addresses. No protection, no abstraction. A single program occupied all of memory.
Fixed Partitions (Early 1960s): Memory divided into fixed-sized partitions. Each partition could hold one process. Problems: internal fragmentation within partitions, inflexibility.
Variable Partitions (Mid 1960s): Partitions sized to fit processes exactly. Eliminated internal fragmentation but created external fragmentation. Compaction required but expensive.
Paging (Late 1960s): The breakthrough. Fixed-size pages solved the fitting problem—any page fits in any frame. First major implementation: Multics (1969) and IBM System/370 (1970).
Virtual Memory (1970s-present): Combined paging with demand loading—pages can be on disk, loaded on demand. Enabled address spaces larger than physical memory.
| Year | System | Contribution |
|---|---|---|
| 1962 | Atlas Computer (Manchester) | First virtual memory system; pioneered the concept of paging |
| 1969 | Multics | Advanced paging with segmentation; influenced Unix and modern systems |
| 1970 | IBM System/370 | Brought paging to commercial mainframes |
| 1978 | VAX-11/780 | Sophisticated virtual memory; influenced later architectures |
| 1985 | Intel 80386 | First x86 processor with full 32-bit paging support |
| 2003 | AMD64/x86-64 | Extended paging to 64-bit address spaces; current standard |
The Atlas Computer:
The Atlas computer, developed at the University of Manchester and operational in 1962, deserves special mention. It was the first machine to implement what we now call virtual memory with demand paging. The Atlas pioneers introduced:
Many concepts we treat as fundamental—page tables, page faults, and replacement policies—were invented for Atlas. The basic architecture of paging has remained remarkably stable for over 60 years, a testament to the elegance of the original design.
Understanding history helps you appreciate that paging isn't arbitrary—every design decision was carefully considered and battle-tested across decades of refinement. When you wonder 'why does paging work this way?', often the answer lies in lessons learned from earlier systems.
We've covered the foundational concepts of paging. Let's consolidate the essential knowledge:
What's Next:
Now that we understand the fundamental concepts of pages and frames, we'll explore the critical topic of page size. The choice of page size has profound implications for system performance, memory utilization, and page table overhead. Different systems have made different choices, and understanding the tradeoffs is essential for systems engineering work.
You now understand the core abstraction of paging: dividing memory into fixed-size units that can be mapped flexibly between logical and physical address spaces. This simple concept—pages mapping to frames—underpins all modern memory management and is essential for understanding virtual memory, demand paging, and beyond.