Level 4 · Chapter 7
Paging & page faults
Why a valid address doesn't mean the data is in RAM right now, and why most page faults are cheap, not catastrophic.
The VAD tree described what a region of virtual memory is for. This chapter is about when the actual physical memory backing it shows up — which, crucially, is often not until the moment code first touches it.
A valid address is a promise, not a guarantee
Reserving and committing virtual address space doesn't necessarily mean physical RAM is allocated immediately. A huge amount of Windows memory activity is genuinely lazy: memory is committed (the address range is reserved and guaranteed to be satisfiable) without physical pages being assigned to it yet. The first time code actually reads or writes a page in that range, the CPU raises a page fault — not an error, in this context, but a normal, expected trap that hands control to the Memory Manager to go figure out what should actually be there.
What the Memory Manager does on a fault
Consulting the VAD covering the faulting address, the Memory Manager has several possible resolutions, roughly in order of how expensive they are:
- Demand-zero. The address belongs to ordinary committed memory (a fresh heap allocation, for instance) with no prior content — the Memory Manager just hands over a zeroed physical page. Cheap, no disk I/O.
- Soft fault. The needed data is already somewhere in physical memory — perhaps it was recently trimmed from this process's working set but hasn't actually been evicted from RAM yet, or it's a page shared with another process (a DLL's code section, mapped by two processes simultaneously) that's already resident from the other process's access. Resolved without touching disk at all.
- Hard fault. The data genuinely isn't in physical memory and has to be read from disk — from the original image or mapped file for something like a DLL's code section, or from the page file for previously-evicted private, modified data. This is the expensive case: an actual disk (or, more commonly today, SSD) I/O operation sits on the critical path before execution can continue.
Why fault rate alone is a misleading performance signal
A process showing a very high page-fault count is not, by itself, evidence of a performance problem — soft faults and demand-zero faults are routine, inexpensive, and happen constantly even on a healthy, fast system; a freshly-started process touching newly committed memory for the first time will generate plenty of them just by running normally. What actually matters for performance is the hard fault rate specifically — faults that genuinely hit disk — since that's the category carrying real, measurable latency. Task Manager and Performance Monitor both expose hard faults as a distinct counter from total page faults precisely because conflating the two produces a misleading read on what's actually slow.
A worked example: the first write after allocation
A common, easily-observed sequence: an application allocates a large buffer (say, VirtualAlloc reserving and committing several megabytes). At the moment of allocation, essentially no physical memory work has happened yet — only the VAD and the commit accounting exist. As the application then writes into that buffer for the first time, each newly-touched page generates a demand-zero fault, handed a fresh zeroed physical page on the spot. This is why large allocations are cheap to make and the real cost shows up gradually, spread across the first time each part of the buffer is actually used — not concentrated at the moment VirtualAlloc itself returns.
A common mistake
Assuming every page fault implies disk activity conflates the cheap, routine cases (demand-zero, soft faults) with the genuinely expensive one (hard faults). This mistake leads people to chase "reduce page faults" as a blanket performance goal, when the actual, useful target — when there's a real problem to fix — is almost always hard faults specifically, since those are the ones with a real, measurable I/O cost attached.
Where this connects
- Working sets & trimming covers what happens under memory pressure — specifically, why previously-resident pages can end up needing a soft or hard fault to bring back.
- The Cache Manager is deeply intertwined with paging for memory-mapped files — the same fault machinery described here is how the cache manager actually serves file data efficiently.