Looking Inside Your Working Set

You may want to get a better understanding of the pieces inside the working set of your application. For example, you may save a lot of code space with the Working Set Tuner only to discover that the code space is only a small portion of your overall working set. In fact, this might even be something you want to do before you go to all the trouble to tune your code.

You probably want to make these measurements on a test computer. Choose a computer large enough to hold your entire working-set tuning test scenario in memory. You may need to discover this size through the trial and error process described in this section.

To do this, you can use a tool called Virtual Address Dump, or VADump. The VADump tool looks inside the working set of a process and determines the nature of each page.

First, link your application using the -debug and -debugtype:coff options, so you get full use from VADump.

Start your application, then start PView. Use PView to note the process identifier of your application. You'll need to supply this to VADump. You should convert the process identifier from hexadecimal to decimal, since VADump expects it in decimal format. Or you can use the TLIST utility to get the process identifier directly in decimal form.

Set up your test scenario. Start Performance Monitor and leave it running, and command window so you can run VADump. Type the following in the command window, but don't press enter yet.

vadump -o -m -p PID > app.vad

The -o option tells VADump to monitor the working set in the original style, the -m option tells VADump to use the mapped symbols, and the -p option indicates the process identifier (PID), in decimal, of the process to measure. In the example command line, the output is directed to the file APP.VAD. Again, do not press ENTER yet.

You should flush everything from memory and the disk cache. You can use the CLEARMEM utility from the Resource Kit. Running CLEARMEM a few times generally completes the flush; however, you may want to watch your working set with Performance Monitor to be sure. Then switch to your application and execute the test scenario you devised for tuning the working set.

Now switch to the VADump window and press the enter key execute the VADump command created earlier. The results will be put in APP.VAD if you use the command line we showed earlier.

Take a look at Performance Monitor again and get the new size for your application's working set. This is likely to be a bit larger now than before, because VADump itself must bring some pages into the working set to scan all the page tables and working set entries for your application.

Run the scenario in your application again. Performance Monitor should get no page faults in your application during this run. If it does, you may not have enough memory on the system to hold your application's working set.

The output from VADump shows the nature of each page in the working set of your process:

0x00010000 PRIVATE Base 0x00010000
0x00020000 PRIVATE Base 0x00020000
0x0012d000 PRIVATE Base 0x00030000
0x0012e000 PRIVATE Base 0x00030000
0x0012f000 PRIVATE Base 0x00030000
0x00130000 PRIVATE Base 0x00130000
0x00140000 PRIVATE Base 0x00140000
0x00141000 Process Heap
0x00142000 Process Heap
0x00143000 Process Heap
0x00240000 PAGEFILE_MAPPED Base 0x00240000
0x00250000 DATAFILE_MAPPED Base 0x00250000 unicode.nls
0x00251000 DATAFILE_MAPPED Base 0x00250000 unicode.nls
0x00253000 DATAFILE_MAPPED Base 0x00250000 unicode.nls
0x00260000 DATAFILE_MAPPED Base 0x00260000 locale.nls
0x00263000 DATAFILE_MAPPED Base 0x00260000 locale.nls
0x00270000 DATAFILE_MAPPED Base 0x00270000 sortkey.nls
0x002c0000 DATAFILE_MAPPED Base 0x002c0000 sorttbls.nls
0x002d0000 PRIVATE Base 0x002d0000
0x002e0000 PAGEFILE_MAPPED Base 0x002e0000
0x002f0000 PRIVATE Base 0x002f0000
0x01000000 menappl.exe
        (1000) _except_list
0x01001000 menappl.exe
        ( 165) LogDisplayDlgProc@16
        (  24) GetSystemPerfData@16
        ( 1a0) UpdateSystemData@8
        (  1c) MemorySize@4
        (  29) GetObjectDefByTitleIndex@8
        (  14) LogCollecting@4
        ( 113) DrawAlerts@8
        (  d2) DrawLog@8
        (  4c) SmallFileSizeString@8
 

The page virtual addresses appear on the left. For each section of address space, the base is shown on the right. PRIVATE pages are dynamic data pages that are private to the process. Process Heap pages are dynamically allocated from the process heap. It can be difficult to determine who is using this space, and you may need to look at pointers within your application using the debugger.

The system pages are those allocated for the page tables and for the working set packing list itself. This might be larger than your application actually needs, because VADump needs to scan them. So use Performance Monitor as described to determine the difference. For this example, when we looked at the working set of Performance Monitor while charting, running VADump added 5 pages to the working set.

If COFF symbols are included and the module was linked with the -debug flag, other pages that belong to specific modules are indicated by listing which public symbols occur within the page. This helps you to understand why a particular page has been brought into memory. If the module was compiled without the correct flags, you will see only the module name.

Any pages listed as belonging to the module "Error" are pages that did not resolve to a particular module.

You will also find some DATA pages at the upper end of the application's address space. These are for such system-related items as the Process Environment Block, the Thread Environment Blocks, the Per-Thread Data Area, and so on.

Pages in the range starting at 0xC0000000 are page table pages. They are listed showing the range of pages they map, how many of those are in memory (these are called resident pages), and the range of resident pages and their modules.

Finally, there is a summary of pages and who owns them. These pages summarize the pages already listed, so avoid counting them again.