Page Faults & Demand Paging
IntermediateA page fault occurs when a process accesses a virtual page not currently in physical RAM, triggering the OS to load it from disk — demand paging loads pages only when first accessed.
Overview
Demand paging is the strategy of not loading a page into RAM until it is actually accessed. When the executable starts, none of its pages are loaded; only the first few that get executed are brought in. Every time the process accesses a virtual address whose page is not in RAM, the MMU raises a page fault exception. The OS page fault handler takes over, finds the page on disk (in the swap area or as a file-backed page), allocates a free physical frame, loads the page, updates the page table entry, and restarts the faulting instruction. Minor page fault: the page is in memory but the page table entry was not set up (e.g., a recently forked child sharing COW pages) — no disk I/O needed. Major page fault: the page truly needs to be loaded from disk — catastrophic for latency since one disk I/O equals millions of CPU cycles.
Page Fault Handler Steps
When a page fault fires, the CPU switches to kernel mode and saves process state. The handler checks whether the faulting address is a valid virtual address for this process (not a null dereference or buffer overflow). If valid, it locates the page on disk (swap or memory-mapped file), finds a free frame (possibly evicting another page), loads the data, marks the PTE valid, and restarts the instruction. If the address is invalid, the process receives SIGSEGV — in Java this appears as a NullPointerException or ArrayIndexOutOfBoundsException.
// Page fault handler (OS pseudocode)
void handlePageFault(Process p, long virtualAddress) {
// 1. Validate: is this address in the process's valid VMA (virtual memory area)?
if (!p.isValidAddress(virtualAddress)) {
sendSignal(p, SIGSEGV); // → Java NullPointerException / OOBE
return;
}
// 2. Check if minor fault (page in memory, PTE not set)
if (isPageInMemory(virtualAddress)) {
updatePageTableEntry(p, virtualAddress); // no disk I/O
return; // minor fault handled
}
// 3. Major fault: find a free frame (or evict a page)
int frame = findFreeFrame();
if (frame == -1) frame = evictPage(); // page replacement algorithm
// 4. Load page from disk (swap or file)
loadPageFromDisk(p, virtualAddress, frame); // ~5ms disk I/O
// 5. Update PTE: mark valid, set frame number
p.pageTable[getPageNumber(virtualAddress)] = frame | VALID_BIT;
// 6. Restart the faulting instruction
}
// Java: triggering page faults deliberately (warm-up vs cold start)
// Cold start: JVM reads class files → major page faults on each new class loaded
// After warm-up: all hot pages in RAM → no page faults → fast executionJava Memory-Mapped Files and Page Fault Performance
Memory-mapped files rely entirely on demand paging — accessing any part of the mapped region that is not yet in RAM triggers a major page fault. This makes initial access slow but subsequent reads fast. For large files (multi-GB), only the accessed pages consume RAM. Java NIO's MappedByteBuffer is the primary API. OutOfMemoryError in Java is not a page fault — it means the JVM heap allocator cannot grow further (heap limit reached or native memory exhausted).
// Measuring page fault impact on memory-mapped file access
Path path = Path.of("large-dataset.bin");
long startMap = System.nanoTime();
try (FileChannel fc = FileChannel.open(path, StandardOpenOption.READ)) {
MappedByteBuffer buf = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
long mapTime = System.nanoTime() - startMap;
System.out.printf("Mapping time: %.2f ms (just reserves VA space)%n",
mapTime / 1e6);
// First access — triggers major page faults (disk I/O)
long startRead = System.nanoTime();
int firstByte = buf.get(0); // page fault → load 4KB from disk
long faultTime = System.nanoTime() - startRead;
System.out.printf("First access (major fault): %.2f ms%n", faultTime / 1e6);
// Second access to same page — already in RAM, no fault
startRead = System.nanoTime();
int sameByte = buf.get(1); // same 4KB page → no fault
long hotTime = System.nanoTime() - startRead;
System.out.printf("Second access (no fault): %.3f µs%n", hotTime / 1e3);
}
// Ratio: major fault ~1-5ms vs hot access ~100ns = 10,000x differenceKey Points to Remember
- 1Demand paging loads pages only when first accessed — program starts instantly without loading everything.
- 2Minor page fault: page is in memory but PTE not set — handled without disk I/O.
- 3Major page fault: page must be loaded from disk — costs ~1–10 ms (millions of CPU cycles).
- 4The page fault handler validates the address, allocates a frame, loads from disk, updates PTE, and restarts.
- 5Java OutOfMemoryError means heap limit reached — not a page fault (that would be transparent to Java).
- 6Memory-mapped files use demand paging — only accessed pages consume RAM, ideal for large datasets.
Interview Questions
Sign in to ask AriaWhat is the difference between a minor and a major page fault?
What steps does the OS take when handling a major page fault?
Why is a Java application slow on the first request after deployment?
How does demand paging allow a process to use more memory than physical RAM?
Ask Aria about Page Faults & Demand Paging
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.