Session 5.1 – Virtual Memory Fundamentals
Understanding virtual memory basics, demand paging, and page faults
Learning Objectives
By the end of this session, you will be able to:
- Understand the fundamental concepts and motivation for virtual memory
- Explain the principles of demand paging and lazy loading
- Analyze the page fault handling process
- Apply the principle of locality to virtual memory systems
- Evaluate the benefits and challenges of virtual memory
- Calculate effective memory access time with page faults
Introduction to Virtual Memory
Virtual memory is a memory management technique that provides an "idealized abstraction of the storage resources that are actually available on a given machine" to create the illusion of a very large memory space.
The Problem
- Limited physical memory (RAM)
- Growing program sizes
- Multiple programs running simultaneously
- Programs need more memory than available
- Inefficient memory utilization
The Solution
- Create illusion of large memory
- Separate logical from physical memory
- Load only needed parts of programs
- Use secondary storage as extension
- Enable multiprogramming beyond RAM limits
KB to MB
~1 cycle
GB range
~100 cycles
TB range
Illusion
TB+ range
~10⁶ cycles
Virtual Memory Concepts
Virtual memory extends the available memory by using secondary storage to simulate additional RAM, allowing programs to execute even when they don't entirely fit in physical memory.
Key Concepts
- Virtual Address Space: Logical memory visible to program
- Physical Memory: Actual RAM available
- Page File/Swap Space: Disk area for virtual memory
- Memory Mapping: Virtual to physical translation
- Page Table: Mapping information storage
- Valid/Invalid Bits: Indicate page location
- Page Replacement: Managing limited physical pages
- Working Set: Pages currently in use
Virtual Memory Architecture
Virtual Address Space
Program's View
(Large Virtual Space)
Page Table
| Page | Frame | Valid |
|---|---|---|
| 0 | 2 | 1 |
| 1 | - | 0 |
| 2 | 0 | 1 |
| 3 | - | 0 |
| 4 | 1 | 1 |
| 5 | - | 0 |
Physical Memory
Hardware View
(Limited Physical RAM)
Secondary Storage
Virtual Memory Benefits
- Program Size Independence: Programs larger than RAM can execute
- Increased Multiprogramming: More processes can run concurrently
- Memory Protection: Processes isolated from each other
- Efficient Memory Use: Load only needed pages
- Simplified Programming: Programmer doesn't manage memory
- File Mapping: Files can be mapped to memory
Demand Paging
Demand paging is a method of virtual memory management where pages are loaded into memory only when they are accessed, rather than loading the entire program at startup.
Demand Paging Process
No pages loaded
CPU references page
Valid bit = 0?
Load from disk
Continue execution
Advantages
- Faster Program Startup: Don't load entire program
- Memory Efficiency: Load only needed pages
- Support Large Programs: Bigger than physical memory
- Better Multiprogramming: More processes can fit
- Lazy Loading: Load on demand
Challenges
- Page Fault Overhead: Disk access is slow
- Complex Management: Page replacement algorithms
- Thrashing Risk: Too many page faults
- Hardware Requirements: MMU support needed
- Unpredictable Performance: Depends on access patterns
Demand Paging Example
Program Execution
main() {
// Page 0
int x = 10;
// Page 1
func1();
// Page 2
func2();
}
void func1() {
// Page 1
printf("Function 1");
}
void func2() {
// Page 2
printf("Function 2");
}
Loading Sequence
No pages in memory
Page fault → Load Page 0
Page fault → Load Page 1
Page fault → Load Page 2
Memory State
After T1: Frame 0: Page 0 ✓ Frame 1: Empty Frame 2: Empty After T2: Frame 0: Page 0 ✓ Frame 1: Page 1 ✓ Frame 2: Empty After T3: Frame 0: Page 0 ✓ Frame 1: Page 1 ✓ Frame 2: Page 2 ✓
Page Fault Handling
A page fault occurs when a program attempts to access a page that is not currently loaded in physical memory. The operating system must handle this exception and load the required page.
Page Fault Handling Algorithm
Page Fault Handler Steps: 1. Trap to OS: Hardware generates page fault interrupt 2. Save State: Store current process state 3. Check Address: Verify address is valid 4. Find Free Frame: - If available → Use it - If not → Run page replacement algorithm 5. Schedule Disk I/O: Read page from secondary storage 6. Block Process: Context switch to another process 7. I/O Completion: Disk interrupt when page loaded 8. Update Page Table: Set valid bit, frame number 9. Resume Process: Restart faulting instruction Time Components: - Interrupt handling: ~1-10 µs - Page replacement: ~100 µs - Disk access: ~1-10 ms - Memory update: ~1 µs
Types of Page Faults
| Type | Cause | Handler Action | Performance Impact |
|---|---|---|---|
| Valid Page Fault | Page not in memory but exists | Load page from disk | High (disk I/O) |
| Invalid Page Fault | Access to invalid address | Send signal to process (SIGSEGV) | Low (terminate process) |
| Protection Fault | Access violates permissions | Send signal to process (SIGBUS) | Low (terminate process) |
| Copy-on-Write | Write to shared read-only page | Create private copy | Medium (memory allocation) |
Page Fault Flow Diagram
Before Page Fault
Virtual Page 3
Valid = 0
Page Fault Triggered!
During Page Fault
Running
or Replace
Load Page 3
Process Blocked
After Page Fault
Contains Page 3
Valid = 1, Frame = N
Successful
Execution Resumed
Principle of Locality
The principle of locality states that programs tend to access a relatively small portion of their address space at any given time. This principle makes virtual memory systems practical and efficient.
Types of Locality
Temporal Locality
Definition: Recently accessed items will be accessed again soon
- Loop variables
- Frequently called functions
- Stack operations
- Recently used data
Spatial Locality
Definition: Items near recently accessed items will be accessed soon
- Sequential program execution
- Array traversals
- Struct member access
- Adjacent memory locations
Locality Example: Array Processing
Code Example:
for (int i = 0; i < 1000; i++) {
sum += array[i] * 2; // Spatial locality: sequential array access
} // Temporal locality: i, sum, array accessed repeatedly
Memory Access Pattern:
Time 1: array[0] → Page 0
Time 2: array[1] → Page 0 (spatial locality - same page)
Time 3: array[2] → Page 0 (spatial locality - same page)
...
Time N: array[255] → Page 1 (spatial locality - next page)
Working Set:
- Variables: i, sum (temporal locality)
- Array: sequential access pattern (spatial locality)
- Code: loop instructions (temporal locality)
- Pages needed: Only 2-3 pages for 1000-element array
Why Locality Helps Virtual Memory
- Predictable Access: Can anticipate future needs
- Small Working Set: Few pages active at once
- Reduced Page Faults: Most accesses hit loaded pages
- Effective Caching: Recently used pages stay in memory
- Better Performance: Fewer expensive disk operations
Locality Metrics
Working Set Size:
W(t, τ) = {pages accessed in window [t-τ, t]}
Locality Ratio:
LR = (Hits in working set) / (Total accesses)
Example:
Program accesses 1000 pages total
Working set size: 50 pages
Locality ratio: 0.95 (95% hits)
Page fault rate: 5%
Benefits and Challenges
Benefits of Virtual Memory
- Program Size Independence: Run programs larger than RAM
- Memory Protection: Process isolation and security
- Memory Sharing: Efficient sharing of code and libraries
- Simplified Memory Management: Automatic allocation
- Increased Multiprogramming: More concurrent processes
- Memory-Mapped Files: Treat files as memory
Challenges and Overheads
- Performance Overhead: Address translation costs
- Page Fault Latency: Disk access is very slow
- Memory Fragmentation: Internal fragmentation in pages
- Thrashing: Excessive page fault activity
- Complex Algorithms: Page replacement strategies
- Hardware Requirements: MMU and TLB needed
Design Trade-offs
| Design Decision | Benefit | Cost | Typical Choice |
|---|---|---|---|
| Page Size | Large: Fewer page faults, better I/O | Large: More internal fragmentation | 4KB-64KB |
| Page Table Size | Large: Faster access, simpler hardware | Large: More memory overhead | Multi-level tables |
| TLB Size | Large: Fewer TLB misses | Large: More expensive hardware | 64-1024 entries |
| Replacement Policy | Complex: Better decisions | Complex: More computation | Approximated LRU |
Performance Analysis
Understanding the performance characteristics of virtual memory systems is crucial for system design and optimization.
Effective Access Time Formula
Basic Formula:
EAT = (1 - p) × memory_access_time + p × page_fault_time
Where:
- EAT = Effective Access Time
- p = Page fault rate (0 ≤ p ≤ 1)
- memory_access_time = Time to access RAM
- page_fault_time = Time to handle page fault
Detailed Formula:
page_fault_time = page_fault_overhead + swap_page_out + swap_page_in + restart_overhead
Example Calculation:
Memory access time: 100 nanoseconds
Page fault rate: 0.001 (0.1%)
Page fault service time: 25 milliseconds = 25,000,000 ns
EAT = (1 - 0.001) × 100 + 0.001 × 25,000,000
= 0.999 × 100 + 0.001 × 25,000,000
= 99.9 + 25,000
= 25,099.9 nanoseconds ≈ 25.1 microseconds
Performance Impact:
Without page faults: 100 ns
With page faults: 25,100 ns
Slowdown factor: 251×
Performance Optimization
- Reduce Page Fault Rate:
- Better replacement algorithms
- Increase physical memory
- Improve locality of reference
- Reduce Page Fault Cost:
- Faster storage (SSDs)
- Compression
- Asynchronous I/O
Performance Metrics
Key Metrics: Page Fault Rate: PFR = Page Faults / Memory Accesses Memory Utilization: MU = Used Pages / Total Pages Thrashing Indicator: TI = Page Fault Time / CPU Time Working Set Size: WSS = Unique pages in time window Acceptable Values: Page Fault Rate: < 0.01 (1%) Memory Utilization: 60-80% Thrashing Indicator: < 0.1
Performance vs Page Fault Rate
Impact of Page Fault Rate on System Performance: Page Fault Rate | Effective Access Time | Performance Impact ----------------|----------------------|------------------- 0.0001 (0.01%) | 2,600 ns | 26× slower 0.001 (0.1%) | 25,100 ns | 251× slower 0.01 (1%) | 250,000 ns | 2,500× slower 0.1 (10%) | 2,500,000 ns |25,000× slower (thrashing) Lesson: Page fault rate must be kept very low for acceptable performance. Even 1% page fault rate makes system nearly unusable!
Practical Examples
Virtual Memory System Analysis
Scenario:
A system with the following characteristics:
- Physical memory: 1 GB (262,144 pages of 4KB each)
- Virtual memory: 4 GB per process
- Page size: 4 KB
- Memory access time: 100 ns
- Average page fault service time: 10 ms
- TLB hit rate: 98%
- TLB access time: 1 ns
Analysis: 1. Address Space Calculations: Pages per process: 4 GB ÷ 4 KB = 1,048,576 pages Page table entries per process: 1,048,576 entries Page table size (4 bytes/entry): 4 MB per process Maximum processes (memory only): 1 GB ÷ 4 MB = 256 processes 2. TLB Performance: TLB hit: 1 ns + 100 ns = 101 ns TLB miss: 1 ns + 100 ns + 100 ns = 201 ns (page table access + memory access) Average TLB access time: 0.98 × 101 + 0.02 × 201 = 103 ns 3. Page Fault Impact (assuming 0.1% page fault rate): No page fault: 103 ns (with TLB) Page fault: 10 ms = 10,000,000 ns Effective access time: 0.999 × 103 + 0.001 × 10,000,000 = 10,103 ns Performance Analysis: Without virtual memory: 103 ns With virtual memory: 10,103 ns Slowdown factor: ~98× Optimization Recommendations: 1. Increase physical memory to reduce page fault rate 2. Use better page replacement algorithms 3. Implement prefetching for sequential access patterns 4. Consider larger page sizes for specific applications
Working Set Analysis
Program: Matrix multiplication (1000×1000 matrices)
Program Structure:
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
for (k = 0; k < 1000; k++) {
C[i][j] += A[i][k] * B[k][j];
}
}
}
Memory Requirements:
Matrix A: 1000 × 1000 × 4 bytes = 4 MB = 1000 pages
Matrix B: 1000 × 1000 × 4 bytes = 4 MB = 1000 pages
Matrix C: 1000 × 1000 × 4 bytes = 4 MB = 1000 pages
Total: 12 MB = 3000 pages
Access Pattern Analysis:
- Matrix A: Row-wise access (good spatial locality)
- Matrix B: Column-wise access (poor spatial locality)
- Matrix C: Single element repeated access (excellent temporal locality)
Working Set Estimation:
Active pages at any time:
- Matrix A: ~1 page (current row)
- Matrix B: ~1000 pages (entire matrix for column access)
- Matrix C: ~1 page (current element)
- Code: ~5 pages
Total working set: ~1007 pages ≈ 4 MB
Performance Prediction:
If physical memory ≥ 4 MB: Minimal page faults
If physical memory < 4 MB: Frequent page faults due to Matrix B
Optimization: Block/tile the multiplication to improve B's locality
Session Summary
Key Concepts
- Virtual Memory: Abstraction providing illusion of large memory
- Demand Paging: Load pages only when accessed
- Page Faults: Hardware exceptions requiring OS intervention
- Locality: Programs access small portion of address space
- Working Set: Pages actively used by process
- Performance: Heavily dependent on page fault rate
Design Principles
- Keep Page Fault Rate Low: Target < 0.01%
- Exploit Locality: Temporal and spatial patterns
- Optimize Common Case: Fast path for memory hits
- Hardware Support: MMU and TLB essential
- Balance Trade-offs: Memory vs performance
- Plan for Worst Case: Handle thrashing
Next Session Preview
Session 5.2 will cover Page Replacement Policies, exploring algorithms like FIFO, Optimal, LRU, and Clock algorithm. We'll analyze their performance characteristics and implementation trade-offs.