The second PFN in Figure 10-42 is for a page on either the standby or the modified list. In this case, the forward and backward link fields link the elements of the list together within the list. This linking allows pages to be easily manipulated to satisfy page faults. When a page is on one of the lists, the share count is by definition 0 (because no working set is using the page) and therefore can be overlaid with the backward link. The reference count is also 0 if the page is on one of the lists. If it is nonzero (because an I/O could be in progress for this page—for example, when the page is being written to disk), it is first removed from the list.
The third PFN in Figure 10-42 is for a page that belongs to a kernel stack. As mentioned earlier, kernel stacks in Windows are dynamically allocated, expanded, and freed whenever a callback to user mode is performed and/or returns, or when a driver performs a callback and requests stack expansion. For these PFNs, the memory manager must keep track of the thread actually associated with the kernel stack, or if it is free it keeps a link to the next free look-aside stack.
The fourth PFN in Figure 10-42 is for a page that has an I/O in progress (for example, a page read). While the I/O is in progress, the first field points to an event object that will be signaled when the I/O completes. If an in-page error occurs, this field contains the Windows error status code representing the I/O error. This PFN type is used to resolve collided page faults.
In addition to the PFN database, the system variables in Table 10-19 describe the overall state of physical memory.
Variable
Description
MmNumberOfPhysicalPages
Total number of physical pages available on the system
MmAvailablePages
Total number of available pages on the system—the sum of the pages on the zeroed, free, and standby lists
MmResidentAvailablePages
Total number of physical pages that would be available if every process was trimmed to its minimum working set size and all modified pages were flushed to disk
EXPERIMENT: Viewing PFN Entries
You can examine individual PFN entries with the kernel debugger
You can also use the MemInfo tool to obtain information about a PFN. MemInfo can sometimes give you more information than the debugger’s output, and it does not require being booted into debugging mode. Here’s MemInfo’s output for those same two PFNs:C:\>meminfo -p 2c9f7 PFN: 2c9f7 PFN List: Active and Valid PFN Type: Page Table PFN Priority: 5 Page Directory: 0x866168C8 Physical Address: 0x2C9F7000 C:\>meminfo -p 2d6c1 PFN: 2d6c1 PFN List: Active and Valid PFN Type: Process Private PFN Priority: 5 EPROCESS: 0x866168C8 [windbg.exe] Physical Address: 0x2D6C1000
MemInfo correctly recognized that the first PFN was a page table and that the second PFN belongs to WinDbg, which was the active process when the
Physical Memory Limits
Now that you’ve learned how Windows keeps track of physical memory, we’ll describe how much of it Windows can actually support. Because most systems access more code and data than can fit in physical memory as they run, physical memory is in essence a window into the code and data used over time. The amount of memory can therefore affect performance, because when data or code that a process or the operating system needs is not present, the memory manager must bring it in from disk or remote storage.