In addition to trimming working sets, once every 4 seconds the Balance Set
Manager can swap out pages that belong to the call stacks of threads that have
been sleeping for more than 7 seconds (3 seconds on systems with less than 19MB
of memory). The call stack is a special type of memory that records the function
invocations a thread makes. If a thread has been asleep (e.g., while waiting for
a user to enter a keystroke) for a long time, the Memory Manager assumes the
thread will sleep for a longer time. If the Balance Set Manager swaps out the
stacks of all the threads in a process, it trims the process' working set to
nothing, and the system assumes that the process is inactive. Swapping out the
stacks of all the threads in a process minimizes the footprints of processes
that don't require memory because they are waiting for infrequent events to
occur before they become active.
The Page Frame Database
Last month, I described how NT organizes physical memory as a list of page
frames, each of which is one page in size (4096 bytes on x86 processors, 8192 bytes on Alphas). The Memory Manager mirrors this list of page frames with its own list--the PFN Database. Each entry in the PFN Database corresponds to a physical page of memory (e.g., entry 5 in the PFN Database corresponds to page frame 5 in physical memory). Entries in the PFN Database record information about the state of data stored in corresponding physical pages.
A physical page can exist in one of eight states, which Table 1, page 64,
describes. Figure 1 illustrates how the Memory Manager adds to a list all the
PFN Database entries that belong to pages in the same state (except pages in the
valid or transition states). For example, all modified pages go on the modified
page list. A given page undergoes several status changes during its lifetime;
therefore, its PFN entry moves among different lists. Figure 1 shows how working
sets are associated with valid pages in the PFN Database.
Let's look at some of these state changes, beginning with a valid page.
Figure 2 depicts the state changes I'll discuss. A page is in the valid state if
it is currently part of a process working set. A valid page can be dirty
or clean--a dirty page is one a process has written to, so that the
page's content in physical memory might be different from its content in a
backing file (either a paging file or a memory-mapped file). The MMU sets a bit
in a page's PTE when a process writes to that page.
When the Balance Set Manager trims a valid page from a working set, the
page moves to one of three lists. If the page is clean, it will move to the
standby list. If the page is dirty, it almost always moves to the modified page
list. In some cases, as when a file system accesses pages backed by files the
file system creates to represent its metadata (such as the FAT on FAT file
systems, or the MFT--Master File Table--on NTFS file systems), a dirty page
moves to the modified no-write page list instead. NTFS takes advantage of this
type of marking so that it can ensure that pages belonging to NTFS logging files
write to disk before file metadata writes to disk.
A page on the modified page list moves to the standby page list after the
Memory Manager's modified page writer writes the page's data to disk. However,
while the modified page writer is writing its data to disk, the page makes a
stop in the transition state (which has no list). A page on the modified
no-write page list moves to the standby page list when the file system instructs
the Memory Manager to move the page. This instruction comes after a log file is safely written to disk, for example. When the number of pages on the modified page list exceeds a threshold, or when free memory drops below a
threshold (based on the amount of physical memory on the system and determined during the boot), one of two modified page writer threads wakes up to perform disk I/O that sends the data to a paging file or a data file.
A page on the standby page list moves to the free page list when the
process that had the page in its working set either frees the virtual memory
associated with the page, or the process terminates (which is another way of
freeing the virtual memory). An interesting optimization based on the lists I've
already discussed is possible. If a page moves from the working set of a process
to the standby page, modified page, or modified no-write page lists, and if that
process subsequently accesses the page before the Memory Manager assigns the
page to a different process, the Memory Manager can place the page back in the
process' working set. This operation is known as soft-faulting (or soft-page
faulting) memory back to a process. Soft-faulting is a way the Memory
Manager can tentatively remove memory from a process but give it back quickly if
the process reaccesses the memory in a short amount of time.
Pages on the standby page list move to the zeroed page list after a special
thread, called the zero-page thread, clears their content. The zero-page thread
executes in the background at priority 0. It runs only if no other thread can
run, and its job is to move pages from the free page list to the zeroed page
list as it clears their content.
When a process accesses a page and the Memory Manager decides that the
process' working set can expand, the Memory Manager checks the zeroed page list
to find a physical page to assign to the process. If the Memory Manager finds a
page in the zeroed page list, it can immediately use the page. If the zeroed
page list is empty, the Memory Manager checks the free page list. If the free
page list is also empty, the Memory Manager checks the standby page list.
Finally, if the standby page list is empty, the Memory Manager's thread waits
while the Balance Set Manager trims a page from a working set, or until a page
shows up on the standby page, free page, or zeroed page lists (e.g., a page
might be in transition, and after it writes to disk it appears on the standby
list).
Prev. page
1
[2]
3
next page