How can I tell how much RAM is being used by application processes and various operating system functions?

It is not possible to get a complete accounting of RAM usage on a Windows, but you can get reasonably close. RAM usage by various OS functions is measured by the following five Memory Object counters:

Pool Nonpaged Bytes: these represent allocations directed to the nonpaged pool, which is a set virtual memory pages that always remain resident in RAM. (These are nonpageable bytes.) Device drivers and the OS use the nonpaged pool to store data structures that must stay in physical memory and can never be paged out to disk. (For example, the TCP/IP driver must allocate some amount of nonpaged memory for every TCP/IP connection that is active on the computer for data structures that are required during processing of network adaptor interrupts when page faults cannot be tolerated.)

Pool Paged Resident Bytes: Most virtual memory pages that are acquired in the Operating System range of virtual addresses can be paged out. The Pool Paged Resident Bytes represent memory locations from the pageable pool that currently reside in RAM.

System Cache Resident Bytes: the system’s file cache occupies a reserved range of virtual memory addresses, some of which may currently reside in RAM. (Cached file segments can also be non-resident, in which case they must be fetched from disk when they are referenced by executing processes.) System Cache Resident Bytes represents segments of the file cache that are currently resident in RAM.

System Code Resident Bytes: memory locations associated with system code that is currently resident in RAM.

System Driver Resident Bytes: memory locations associated with device driver code that is currently resident in RAM.

These five Counters account for RAM usage of virtual memory associated with operating system (and device driver) functions. As discussed above, Available Bytes represents free RAM that is not allocated to any OS function or to any executing process.

Once you know how much OS function are currently using, it ought to be a simple matter to account for RAM usage completely by factoring in the Working Set Bytes of various executing processes, as follows:

Process(_Total) Working Set Bytes = Sizeof(RAM) – (Available Bytes + Pool Nonpaged Bytes + Pool Paged Resident Bytes + System Cache Resident Bytes + System Code Resident Bytes + System Driver Resident Bytes)

However, resident pages associated with shared DLLs (e.g., DLLs like comsvcs.dll, mfc42.dll, msvbvm60.dll, etc.) are counted in each and every process Working Set that references a shared DLL. Because these resident pages are counted multiple times, Process(_Total) Working Set bytes usually reports a higher number of resident pages than are actually in use. In other words,

Sizeof(RAM) < Process(_Total) Working Set Bytes + Available Bytes + Pool Nonpaged Bytes + Pool Paged Resident Bytes + System Cache Resident Bytes + System Code Resident Bytes + System Driver Resident Bytes

Because the numbers do not add up as they seemingly ought to, we prefer creating a report like Figure 1 above that charts the six system Memory counters (including Available Bytes) and compares their sum to the amount of installed RAM. Process working sets fill the amount of RAM left over after you have accounted for these six counters, even though you cannot pin down precisely which how much memory each process occupies.


Comments are closed.