The Depths of Windows Memory (Part 1) — The Moment a Virtual Address Becomes Physical RAM: A Page Fault from Start to Finish

· Updated: · · Windows, Memory Management, VirtualAlloc, Page Fault, VAD, Performance Monitoring

Revision history (first version, published Aug 20, 2026)
First published
Cite this article(DOI (registered archive): 10.5281/zenodo.22170859)

The DOIs below refer to previously archived versions and may not match the current text. Use this page’s URL to reference the current text.

Go Komura (2026). The Depths of Windows Memory (Part 1) — The Moment a Virtual Address Becomes Physical RAM: A Page Fault from Start to Finish. KomuraSoft LLC. https://comcomponent.com/en/blog/windows-memory-internals-page-fault/

DOI (registered archive)
10.5281/zenodo.22170859
DOI (last registered version)
10.5281/zenodo.22170860

“I committed 256MiB, but the Working Set did not grow by the same amount.” This question, which comes up when you use VirtualAlloc, is the starting point of Part 1.

For ordinary private memory, committing a page and placing that page in physical RAM are separate things. Windows delays assigning physical pages until the application actually touches them. When the first access causes a page fault, the memory manager examines the VAD, the PTE, the protection attributes, and the backing store, and binds the necessary RAM one page at a time.1

This article follows the path that “the first byte you touch” takes until it reaches physical RAM. If you want to sort out what the numbers Working Set and Commit mean first, see the introductory article “What Does Windows’ “Memory Usage” Actually Mean? — Correctly Reading Working Set, Private Bytes, Commit, and the Page File”. This series does not redefine those terms; it digs into why the numbers come out the way they do from the mechanism up.

“The Depths of Windows Memory” — All 3 Parts

This series proceeds in the order obtaining a physical page → following residency and reclamation → understanding sharing and privatization.

Part Theme What this part follows
Part 1 (this article) Virtual addresses and page faults When a region allocated with VirtualAlloc obtains physical RAM
Part 2 The life of a physical page The state transitions of a page that leaves the Working Set, and the role of the page file
Part 3 Section objects and copy-on-write How DLLs, file mappings, and shared memory share physical pages

Part 1 answers exactly one question.

At what moment does a committed virtual address become physical RAM?

Before you start Details
Intended readers Developers and operators who want to understand memory usage, page faults right after startup, 0xC0000005, and the numbers in VMMap and PerfMon from the mechanism up
Environment Windows 10/11 or current Windows Server
Background knowledge Pointers and the basics of VirtualAlloc
Difficulty Intermediate. No experience with page-table bit layouts or a kernel debugger is required

We use the names of internal structures, but we do not assume undocumented layouts that depend on a particular Windows build.

In the diagram a solid line marks a relation that always holds and a dashed line marks a conditional one (the conditions are given per relation on the detail page). The full list of relations (14 in total, with evidence and certainty) and the definitions of the main concepts are collected on the knowledge map detail page (in Japanese). Data: JSON-LD / Turtle

1. The Bottom Line First

For ordinary private memory, separating the following three stages brings the difference between Commit and Working Set into view.

  1. Reserve is the stage that claims an address in virtual space. It reserves the range, but assigns no physical storage in RAM or in the page file.1
  2. Commit is the stage where the system promises that it will be able to keep the contents in the future. It charges a commit fee and increases Commit Total, but normally does not yet bind physical RAM to every page.12
  3. Touch is the stage where a physical page actually becomes necessary. The first access raises a page fault, and if the access is legitimate, the memory manager assigns a physical page and re-executes the instruction.

MEM_COMMIT is not an order that says “allocate RAM right now”. It is not an empty promise either: it is a system-wide promise that the contents can be kept in the future, in RAM or in an appropriate backing store. The fact that the initial contents of a committed page are zero and the fact that no physical page is assigned until first access are perfectly compatible.1

The understanding that “Reserve/Commit only write to the VAD” is also inaccurate. Reserve mainly creates a VAD that represents the range and its attributes; Commit increases the system’s Commit Total and records the committed state of the range. The intermediate levels of the page table and the individual PTEs are built lazily, at the point they become necessary.

What you want to know Sections to read
What changes at Reserve, Commit, and Touch Sections 2 to 3
What the VAD, PTE, and TLB decide Sections 4 to 6
Separating normal faults from I/O waits and exceptions Sections 7 to 9
Confirming it with numbers on your own machine Sections 10 to 11
What happens at Reserve, Commit, and first accessMEM_RESERVE records the range and attributes in the VAD, MEM_COMMIT consumes Commit Total to promise storage, and the page fault on first access assigns a physical page and adds it to the Working Set1. MEM_RESERVE2. MEM_COMMIT3. First access (Touch)Record the range and attributes in the VADConsume Commit Total (no physical page yet)Page faultBind a zeroed physical page to the PTEAdd to the Working Set and re-execute the instruction

Figure 1: Reserve, Commit, and Touch are separate events. Physical RAM is bound only at the last step, the first access.

2. Three Ledgers That Track a Virtual Page

The ledgers Windows keeps look at the same memory in different units. First, separate the three: range, virtual page, and physical page.

Ledger Unit Role
VAD Virtual address range Manages what the region is, Reserve/Commit, protection, and section correspondence
Page table / PTE Virtual page Represents the current translation to a physical page, or a not-yet-materialized state
PFN database Physical page Tracks the ownership, references, and state of each RAM page

The VAD holds information about a range, the PTE about a virtual page, and the PFN database about a physical page. The page-fault handler cross-checks these to decide whether the access can continue.

Three ledgers from a virtual address to physical RAMA virtual address is managed by the VAD at range granularity and by the PTE at virtual-page granularity, and the PFN database tracks the physical page that the PTE translates to at physical-page granularityDecides Reserve/Commit and protectionValid translationVirtual addressVAD (range ledger)PTE (virtual-page ledger)PFN database (physical-page ledger)Physical RAM page

Figure 2: Three ledgers at different granularities. Fault handling cross-checks the VAD and the PTE, then applies the result on the PFN side.

This article centers on the VAD and the PTE. Part 2 looks at the PFN database from the physical-page side.

3. Reserve, Commit, and Touch Are Separate Events

3.1. Reserve — Claiming an Address

First, reserve a contiguous 256MiB virtual address range.

void* base = VirtualAlloc(
    nullptr,
    256ull * 1024 * 1024,
    MEM_RESERVE,
    PAGE_NOACCESS);

All that happened at this point is that an address was claimed in the process’s virtual space so that other allocations cannot use this range. MEM_RESERVE assigns no physical storage, in RAM or in the page file.1

Because a 64-bit process has a vast virtual space at its disposal, a design that reserves a large range up front and commits only the parts it needs later becomes practical.

3.2. Commit — Promising That the Contents Can Be Kept

Next, commit the reserved range.

void* committed = VirtualAlloc(
    base,
    256ull * 1024 * 1024,
    MEM_COMMIT,
    PAGE_READWRITE);

On success, the promised amount increases, which shows up in the system’s Commit Total and usually in the process’s Private Bytes. Even so, 256MiB of physical pages do not line up all at once. Ordinary pages remain physically unassigned until first access.12

So what is the point of Commit? It is that when the system cannot take on the promise, it can return failure at Commit time rather than in the middle of using the memory.

3.3. Touch — When a Physical Page Becomes Necessary

Finally, the following assignment writes to the first page for the first time.

static_cast<unsigned char*>(base)[0] = 1;

The CPU tries to translate the virtual address to a physical address, but the PTE does not yet hold a valid translation to a physical page. This is where the page fault occurs.

The memory manager, which receives control, determines that this is “a first access to a committed, writable private page”, obtains a zeroed physical page, binds it to the PTE, and adds it to the Working Set. It then has the failed write instruction executed once more.

From the app’s point of view it is just an assignment, but internally control enters the kernel in the middle of the assignment, a physical page is assigned, and execution returns to the same instruction.

4. The VAD — the Range Ledger of Virtual Space

VAD stands for Virtual Address Descriptor, and Windows manages a process’s in-use address ranges as a tree of VADs. With WinDbg’s !vad command you can inspect the start and end VPNs, Commit, protection attributes, Private/Mapped, the Control Area, and more.3

The representative information a VAD carries is as follows.

  • The start and end of the address range
  • The kind, such as Private, Mapped, or Image
  • The Reserve/Commit state
  • Protection such as read, write, execute, and Copy-on-Write
  • Correspondence to a file or section
  • Special attributes such as guard pages

The reason for keeping it per range is to reduce management overhead. 256MiB comes to 65,536 pages when converted to 4KiB pages.

Rather than building a complete management structure for every page from the start, the VAD manages “this contiguous range is one reservation”. On top of that, pages are materialized as they become necessary.

4.1. Finding a VAD Does Not Guarantee Recovery

The explanation “if it is in a VAD the fault is resolved, and if it is not, you get an access violation” is convenient as an entry point, but it oversimplifies. Even when a VAD is found, ordinary access cannot continue in cases such as the following.

  • Only Reserve was done, and the target page is not committed
  • The page is PAGE_NOACCESS
  • A write was made to a read-only page
  • An instruction was executed from a non-executable page
  • A guard page was touched for the first time
  • The access fell outside the valid range of a section

Conversely, even when the PTE is invalid, if the software state of the VAD and the PTE shows that the access is legitimate, it can be resolved as demand-zero, a Transition restore, a page-in, or CoW. To put it precisely, the answer is that the VAD, the PTE, the protection attributes, and the access type are evaluated together.

5. Page Tables and the TLB

The pointer an app holds is a virtual address. For the CPU to access RAM, it must translate the virtual page number into a physical page number. That hierarchical translation table is the page table, and its leaf entry is the PTE (Page Table Entry).

A valid PTE conceptually holds the PFN, read/write/execute protection, whether user mode may access it, Accessed/Dirty, and similar information. The actual bit layout depends on the CPU and the Windows version.

That said, walking the page table every time would be far too slow, so the CPU caches recent translation results in the TLB (Translation Lookaside Buffer). Address translation proceeds in the following order.

  1. If the TLB has a translation and the access conforms to its protection, that result is used.
  2. If the TLB has no translation, the CPU walks the page table.
  3. If there is a valid PTE and the access also conforms to the protection, the translation is registered in the TLB and execution continues.
  4. If there is no valid translation, or there is a protection violation, control proceeds to the page-fault entry point. The protection check is performed even when the translation came from the TLB.

The point that is easy to confuse here is that a TLB miss and a page fault are different things.

Situation What happens next
The TLB has a translation and the access conforms to the protection Continue with the cached translation
The TLB has no translation, but there is a valid PTE and the access conforms to the protection Obtain the translation with a page-table walk and continue
There is no valid translation, or the access violates the protection Proceed to the page-fault entry point

The protection check also works on a TLB hit. A write to a read-only page, or instruction execution on a non-executable page, faults even when the translation is already cached. This is also why a write to a CoW page can fault.

Address-translation flow and the page-fault entry pointEven if the TLB has a translation, an access that does not conform to the protection proceeds to the page-fault entry point. If the TLB has no translation the page table is walked, a valid PTE whose protection also conforms is registered in the TLB and execution continues, and an invalid translation or protection violation proceeds to the page-fault entry pointYesConformsProtection violationNoYesInvalid or protection violationMemory accessDoes the TLB have a translation?Does the access conform to the protection?Continue with that translationTo the page-fault entry pointPage-table walkValid PTE and protection also conforms?Register in the TLB and continue (no fault)

Figure 3: A TLB miss can be resolved by a page-table walk. Control proceeds to a page fault when the translation is invalid or there is a protection violation, and a protection violation can occur even on a TLB hit.

5.1. An Invalid PTE Is Not Merely a Blank

Calling a PTE invalid does not mean its contents are empty. From the software state of an invalid PTE, Windows distinguishes cases such as the following.

  • A demand-zero page that has never been materialized
  • A Transition page that remains in RAM
  • A shared page that refers to a Prototype PTE
  • A private page saved in the page file
  • A protection violation or an invalid region

The CPU’s job ends at deciding “this is not an ordinary valid translation” and handing it to the kernel; the memory manager supplies the meaning from there.

6. A Page Fault from Start to Finish

Let us follow a first write to a committed private page in six stages.

  1. The CPU tries to write.
    It checks the TLB and the page table, but the target PTE has no valid PFN.
  2. The CPU raises a page fault.
    It passes the faulting virtual address, the read/write/execute type, user/kernel, and whether the cause is a missing translation or a protection violation to the kernel.
  3. The memory manager examines the VAD and the PTE.
    It decides whether the page is committed, whether the access conforms to the protection, and which of demand-zero, Transition, shared, page-in, CoW, or exception applies.
  4. If it is demand-zero, a zeroed physical page is obtained.
    A newly handed-out page must be zero so that another process’s data is not leaked.
  5. The PTE and the PFN management information are updated.
    The PFN and the protection are set in the PTE, the physical page is made Active, and it is added to the process’s Working Set.
  6. The failed instruction is re-executed.
    Because the fault resolved normally, no user-mode exception is delivered, and the app continues as if it were an ordinary assignment.

ETW page-fault events also record Transition, Demand Zero, Copy-on-Write, Guard Page, Hard Page Fault, and Access Violation as distinct kinds.4

In other words, a page fault is not a word that means “abnormal” from the start. It is the common entry point for asking the OS to decide when the CPU could not translate on the ordinary path.

Where a page fault is resolvedThe memory manager evaluates the VAD, the PTE, the protection attributes, and the access type, and dispatches to demand-zero, reconnecting a page still in RAM, a hard fault from a backing store, copy-on-write, a guard-page notification, or an exceptionFirst accessStill in RAMDisk read requiredCoW writeGuard pageUnresolvablePage fault occursEvaluate VAD, PTE, protection, and typeDemand-zero (soft)Reconnect from Standby etc. (soft)Hard fault (disk I/O)Copy and swap the PTEClear the guard and notifyException (0xC0000005 etc.)

Figure 4: Faults that enter through the same entry point split into six kinds of outcome depending on the evaluation. Guard pages are covered in detail in section 9.

7. Demand-Zero — a Soft Fault That Does Not Read Disk

Demand-zero is the representative soft fault that occurs when a committed private page is touched for the first time. Microsoft’s Working Set documentation also lists “the process references an allocated virtual page for the first time” as an example of a soft fault.5

Demand-zero has the following characteristics.

  • There is no need to read original data from disk
  • The initial contents are zero
  • An available physical page is bound
  • Working Set and the cumulative Page Fault Count increase
  • This handling alone does not increase Memory\\Pages Input/sec

That is why a spike in Page Faults/sec right after startup does not by itself mean that storage is saturated.

7.1. Lazy Allocation Trades RAM for First-Access Cost

If you commit 256MiB but actually use only 8MiB, lazy allocation, which keeps the remaining 248MiB out of RAM, is reasonable. In exchange, first access carries the cost of fault handling.

For latency-critical work, you may choose to “prefault” by touching each page before starting. This is not a free optimization, however. It is a choice to finish the first-access handling in advance at the cost of also increasing RAM residency in advance.

8. Soft Faults and Hard Faults

The dividing line is whether a read I/O from a backing store is necessary. The number of page faults alone does not reveal this difference.

8.1. Soft Faults

A soft fault is a fault that can be resolved without a read I/O to a backing store. Representative examples are as follows.

  • Demand-zero
  • Reconnecting a page that remains on Standby/Transition
  • Connecting a shared page that is in another process’s Working Set
  • Connecting a page that has already been prefetched
  • Copy-on-Write whose original page is resident

There is CPU cost for the kernel transition, locks, PTE/PFN updates, TLB coherence, and the like, but there is no storage wait.5

8.2. Hard Faults

On the other hand, when the needed page is nowhere in RAM and must be read from a backing store, that is a hard fault. The read source in this case is not only the page file.

  • A private page that was written out to the page file
  • A memory-mapped file
  • An EXE or DLL image
  • A data file referenced by the file cache

ETW HardFault events include FileObject, ReadOffset, and ByteCount, so the actual read source can be tracked.6

Therefore, Hard Fault = a read of pagefile.sys is not true.

When a backing-store read becomes necessary, the request enters the Windows I/O stack. The flow of IRPs and of issue and completion is covered in “The Depths of Windows I/O (Part 1)”, and the junction with the file cache in “The Depths of Windows I/O (Part 4)”. If the page is in RAM, the memory manager alone can return; if it is not, it issues I/O and makes the faulting thread wait until completion.

9. An Unresolvable Fault Becomes an Exception

A fault that, even after the VAD and the PTE are examined, cannot be resolved as a legitimate allocation, page-in, or CoW is delivered to user mode as an exception.

9.1. When It Becomes an Access Violation

The representative case is STATUS_ACCESS_VIOLATION, exception code 0xC0000005. It occurs on a read, write, or execute of an invalid address; the first exception parameter indicates the access type and the second the violating address.7

The typical patterns in which it occurs are as follows.

  • Reading NULL, a freed address, or an address outside an array
  • Writing to a read-only page
  • Executing an instruction from a page that DEP/NX has made non-executable
  • Touching a reserved range that is not committed

9.2. A Guard Page Is Used as a One-Time Notification

Note that PAGE_GUARD has a slightly different meaning. It is a mechanism that notifies you of an access exactly once, raising STATUS_GUARD_PAGE_VIOLATION, and it is used for things such as stack growth.8

Normal lazy allocation, page-in, CoW, a guard notification, and a final access violation all gather, from the CPU’s point of view, at the same page-fault entry point. What decides the outcome is the combination of the VAD, the PTE, the protection attributes, and the access type.

10. See It for Yourself

The purpose of the experiment is to observe the stage where Commit increases and the stage where Working Set increases as separate stages.

The following C++ program reserves 256MiB, commits it, writes one byte to each page, and finally releases it. It waits for the Enter key at each stage, so you can check the values in VMMap and PerfMon there.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <psapi.h>

#include <cstdio>
#include <cstdlib>

#pragma comment(lib, "Psapi.lib")

constexpr SIZE_T kSize = 256ull * 1024 * 1024;

void PrintMemory(const char* stage)
{
    PROCESS_MEMORY_COUNTERS_EX c{};
    c.cb = sizeof(c);
    if (!GetProcessMemoryInfo(
            GetCurrentProcess(),
            reinterpret_cast<PROCESS_MEMORY_COUNTERS*>(&c),
            sizeof(c))) {
        std::printf("GetProcessMemoryInfo failed: %lu\n", GetLastError());
        return;
    }

    std::printf(
        "%-10s WS=%zu MiB  Private=%zu MiB  Faults=%lu\n",
        stage,
        c.WorkingSetSize / 1024 / 1024,
        c.PrivateUsage / 1024 / 1024,
        c.PageFaultCount);
}

void Pause(const char* message)
{
    PrintMemory(message);
    std::puts("Press Enter...");
    (void)std::getchar();
}

int main()
{
    SYSTEM_INFO si{};
    GetSystemInfo(&si);
    std::printf("PID=%lu, page=%lu bytes\n",
                GetCurrentProcessId(), si.dwPageSize);

    void* base = VirtualAlloc(nullptr, kSize, MEM_RESERVE, PAGE_NOACCESS);
    if (!base) {
        std::fprintf(stderr, "Reserve failed: %lu\n", GetLastError());
        return EXIT_FAILURE;
    }
    Pause("reserved");

    if (!VirtualAlloc(base, kSize, MEM_COMMIT, PAGE_READWRITE)) {
        std::fprintf(stderr, "Commit failed: %lu\n", GetLastError());
        VirtualFree(base, 0, MEM_RELEASE);
        return EXIT_FAILURE;
    }
    Pause("committed");

    auto* bytes = static_cast<volatile unsigned char*>(base);
    for (SIZE_T offset = 0; offset < kSize; offset += si.dwPageSize) {
        bytes[offset] = 1;
    }
    Pause("touched");

    if (!VirtualFree(base, 0, MEM_RELEASE)) {
        std::fprintf(stderr, "Release failed: %lu\n", GetLastError());
        return EXIT_FAILURE;
    }
    Pause("released");
}

From Visual Studio’s x64 Native Tools Command Prompt, you can build it with the following command.

cl /std:c++20 /EHsc /W4 memory_fault_demo.cpp

10.1. What to Look at in VMMap

VMMap is a tool that displays reserved virtual memory, Commit, Working Set, Private, and Shareable by type.9 The changes to expect at each stage are as follows.

Stage Expected change
Reserve The Size of Address Space increases, but Commit/WS do not increase by the same amount
Commit Private Commit increases by about 256MiB
Touch Working Set and Private WS increase substantially, and the Fault Count increases as well
Release The target range disappears, and Commit and WS drop

Look at the Change Between Stages, Not for Matching Numbers

The actual numbers vary with the runtime, security products, memory pressure, and the timing of the observation. Look at which way the numbers moved between stages, not at whether they come out to exactly 256MiB.

10.2. Separating Soft and Hard in PerfMon

In PerfMon, place the following counters on the same timeline.

  • Process(<target>)\\Page Faults/sec
  • Memory\\Pages Input/sec
  • Memory\\Page Reads/sec
  • Memory\\Available MBytes
  • Process(<target>)\\Working Set - Private
  • Process(<target>)\\Private Bytes

Process\\Page Faults/sec includes both soft and hard faults. Memory\\Pages Input/sec, on the other hand, is the number of pages read from disk to resolve hard faults.10

In the Touch stage of this program, Page Faults/sec should jump while Pages Input/sec should not rise much. Newly committed pages are materialized by demand-zero, so there is no need to read original data from disk.

Confirm Processes With the Same Name by PID Too

Note that when several processes share the same name, PerfMon numbers such as process#1 can change across restarts. Cross-check against a counter that displays the PID, or identify the process by PID with Process V2 or ETW/WPA.

11. Three Misreadings to Avoid in Practice

11.1. “Commit went up, so it is a RAM leak”

Commit is the promised amount of contents to keep, and untouched pages may not be resident in RAM. To judge a leak, look at the time series of Private Bytes, the breakdown of allocations, and whether the figure returns to its baseline after processing ends.

11.2. “Page Faults/sec is high, so the disk is slow”

Soft faults involve no disk I/O. Look at Page Faults/sec, Pages Input/sec, and storage wait separately, and if necessary follow the source file and the stack with ETW HardFault events.

11.3. “Emptying the Working Set will fix the leak”

Removing pages from the Working Set releases neither Commit nor ownership. The pages move to Standby or Modified and simply fault back in later. To fix a leak, the allocator has to perform VirtualFree, a heap free, object destruction, or the like.

Where that removed physical page goes is what Part 2 follows.

12. Summary

  • MEM_RESERVE claims a virtual address range but assigns no physical storage in RAM or the page file.1
  • MEM_COMMIT consumes Commit and guarantees that the contents can be kept in the future, but an ordinary physical page is not assigned until first access.12
  • The VAD is the ledger of ranges, the PTE of virtual pages, and the PFN database of physical pages.
  • A TLB miss is not a page fault. If there is a valid PTE, a page-table walk alone resolves it.
  • Demand-zero, a Transition restore, and connecting a shared page are soft faults that can be resolved with no disk I/O.5
  • If a read from the page file, a DLL, an EXE, or a mapped file is required, it is a hard fault.6
  • If inspecting the VAD, the PTE, and the protection attributes cannot resolve the fault, it becomes an exception such as 0xC0000005.7
  • For a performance judgment, do not look at Page Faults/sec alone; look at Pages Input/sec, Available, Working Set, Private Bytes, and storage wait on the same timeline.

Continued in Part 2, “The Life of a Physical Page: Five Lists and the Truth About the Page File”.

After the Commit promise has been turned into a physical page, we follow where that page goes once it leaves the Working Set, through the PFN database and the page lists.

KomuraSoft LLC handles investigations of Windows application memory usage, access violations, startup delays, paging, and native-code defect analysis.

References

  1. Microsoft Learn, VirtualAlloc function. On MEM_RESERVE reserving a virtual address range without assigning physical storage, MEM_COMMIT charging a commit fee against the system’s overall memory and page file, the initial contents of a committed page being zero, and the actual physical page not being assigned until it is accessed. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8

  2. Microsoft Learn, PERFORMANCE_INFORMATION structure. On CommitTotal being the current number of committed pages in the system, and CommitLimit being the upper bound that can be committed without extending the page file. ↩ ↩2 ↩3

  3. Microsoft Learn, !vad (WinDbg). On !vad displaying the VAD tree and letting you inspect the start and end VPNs, Commit, Mapped/Private, protection attributes, the Control Area, and more. ↩

  4. Microsoft Learn, PageFault_TypeGroup1 class. On ETW distinguishing and recording Transition Fault, Demand Zero Fault, Copy-on-Write, Guard Page Fault, Hard Page Fault, and Access Violation. ↩

  5. Microsoft Learn, Working Set. On a soft fault being resolvable without accessing a backing store, and occurring from another process’s Working Set, Transition, first-reference demand-zero, and the like. ↩ ↩2 ↩3

  6. Microsoft Learn, PageFault_HardFault class. On a HardFault event including FileObject, ReadOffset, ByteCount, VirtualAddress, and a Thread ID, so that the read source can be tracked. ↩ ↩2

  7. Microsoft Learn, Access Violation C0000005. On 0xC0000005 occurring on a read, write, or execute of an invalid memory address, and the exception parameters indicating the access type and the violating address. ↩ ↩2

  8. Microsoft Learn, Creating Guard Pages. On PAGE_GUARD providing a one-shot notification of page access and raising STATUS_GUARD_PAGE_VIOLATION. ↩

  9. Microsoft Learn, VMMap - Sysinternals. On VMMap breaking down committed virtual memory by type and displaying each type’s Working Set and a detailed address map. ↩

  10. Microsoft Learn, Performance Analysis of Logs (PAL) Tool. On Memory\\Pages Input/sec being the number of pages read from disk to resolve hard page faults. ↩

Recent articles sharing the same tags. Deepen your understanding with closely related topics.

These topic pages place the article in a broader service and decision context.

This article connects naturally to the following service pages.

Frequently Asked Questions

Common questions about the topic of this article.

Is RAM allocated at the moment VirtualAlloc is called with MEM_COMMIT?
For ordinary private memory, Commit consumes the system's commit headroom, but the corresponding physical pages are not assigned until they are first accessed. A page first touched by a write obtains its physical page during demand-zero fault handling.
Does a page fault mean something is wrong or that there is a performance problem?
No. Soft faults that involve no disk I/O, such as demand-zero or returning a page from Standby, are normal operation. For a performance judgment, look not only at Page Faults/sec but also at Pages Input/sec, storage wait, and Available MBytes.
Are a TLB miss and a page fault the same thing?
They are different. Even if the TLB has no translation, if the PTE in the page table is valid the CPU simply walks the table and re-registers the translation. Control proceeds to the page-fault entry point when the PTE is invalid or there is a protection violation.
If the address range is in a VAD, can an access violation still occur?
It can. In addition to whether a VAD exists, the memory manager evaluates Reserve versus Commit, the read/write/execute protection attributes, guard pages, the PTE state, and more. If the fault cannot be resolved, it becomes an exception such as 0xC0000005.
Does a high Page Faults/sec mean the system is short on RAM?
You cannot tell from that alone. Page Faults/sec also includes large numbers of soft faults. You need to correlate it on the same timeline with Memory\Pages Input/sec, Memory\Page Reads/sec, Available MBytes, and disk wait time.

Author Profile

Profile page for the article author.

Go Komura

Representative of KomuraSoft LLC

Focused on Windows software development, technical consulting, and investigations into failures that are difficult to reproduce.

Back to the Blog