Virtual Memory Status

[Previous] [Next]

A Windows function called GlobalMemoryStatus retrieves dynamic information about the current state of memory:

 VOID GlobalMemoryStatus(LPMEMORYSTATUS pmst); 

I think that this function is poorly named—GlobalMemoryStatus implies that the function is somehow related to the global heaps in 16-bit Windows. I think that GlobalMemoryStatus should have been called something like VirtualMemoryStatus instead.

When you call GlobalMemoryStatus, you must pass the address of a MEMORYSTATUS structure. The MEMORYSTATUS data structure is shown below.

 typedef struct _MEMORYSTATUS { DWORD dwLength; DWORD dwMemoryLoad; SIZE_T dwTotalPhys; SIZE_T dwAvailPhys; SIZE_T dwTotalPageFile; SIZE_T dwAvailPageFile; SIZE_T dwTotalVirtual; SIZE_T dwAvailVirtual; } MEMORYSTATUS, *LPMEMORYSTATUS; 

Before calling GlobalMemoryStatus, you must initialize the dwLength member to the size of the structure in bytes—that is, the size of a MEMORYSTATUS structure. This initialization allows Microsoft to add members to this structure in future versions of Windows without breaking existing applications. When you call GlobalMemoryStatus, it will initialize the remainder of the structure's members and return. The VMStat sample application in the next section describes the various members and their meanings.

If you anticipate that your application will run on machines with more than 4 GB of RAM or if the total swap file size might be larger than 4 GB, you may want to use the new GlobalMemoryStatusEx function:

 BOOL GlobalMemoryStatusEx(LPMEMORYSTATUSEX pmst); 

You must pass to this function the address of the new MEMORYSTATUSEX structure:

 typedef struct _MEMORYSTATUSEX { DWORD dwLength; DWORD dwMemoryLoad; DWORDLONG ullTotalPhys; DWORDLONG ullAvailPhys; DWORDLONG ullTotalPageFile; DWORDLONG ullAvailPageFile; DWORDLONG ullTotalVirtual; DWORDLONG ullAvailVirtual; DWORDLONG ullAvailExtendedVirtual; } MEMORYSTATUSEX, *LPMEMORYSTATUSEX; 

This structure is identical to the original MEMORYSTATUS structure except that all the size members are 64 bits wide, allowing for values greater than 4 GB. The member at the end, ullAvailExtendedVirtual, indicates the size of unreserved memory in the very large memory (VLM) portion of the virtual address space of the calling process. This VLM portion applies only to certain CPU architectures in certain configurations.

The Virtual Memory Status Sample Application

The VMStat application ("14 VMStat.exe"), listed in Figure 14-2, displays a simple dialog box that lists the results of a call to GlobalMemoryStatus. The information inside the dialog box is updated once every second, so you might want to keep the application running while you work with other processes on your system. The source code and resource files for the application can be found in the 14-VMStat directory on the companion CD-ROM. The figure below shows the result of running this program on Windows 2000 using a 128-MB Intel Pentium II machine.

The dwMemoryLoad member (shown as Memory Load) gives a rough estimate of how busy the memory management system is. This number can be anywhere from 0 to 100. The exact algorithm used to calculate this value varies between Windows 98 and Windows 2000. The algorithm is also subject to change in future versions of the operating system. In practice, the value reported by this member variable is useless.

The dwTotalPhys member (shown as TotalPhys) indicates the total number of bytes of physical memory (RAM) that exist. On this 128-MB Pentium II machine, this value is 133,677,056, which is just 540,672 bytes under 128 MB. The reason that GlobalMemoryStatus does not report the full 128 MB is that the system reserves some storage as a nonpaged pool during the boot process. This memory is not even considered available to the kernel. The dwAvailPhys member (shown as AvailPhys) indicates the total number of bytes of physical memory available for allocation.

The dwTotalPageFile member (shown as TotalPageFile) indicates the maximum number of bytes that can be contained in the paging file(s) on your hard disk(s). Although VMStat reported that the paging file is currently 318,574,592 bytes, the system can expand and shrink the paging file as it sees fit. The dwAvailPageFile member (shown as AvailPageFile) indicates that 233,046,016 bytes in the paging file(s) are not committed to any process and are currently available should a process decide to commit any private storage.

The dwTotalVirtual member (shown as TotalVirtual) indicates the total number of bytes that are private in each process's address space. The value 2,147,352,576 is 128 KB short of being exactly 2 GB. The two partitions from 0x00000000 through 0x0000FFFF and from 0x7FFF0000 through 0x7FFFFFFF of inaccessible address space account for the 128-KB difference. If you run VMStat under Windows 98, you'll see that dwTotalVirtual comes back with a value of 2,143,289,344, which is just 4 MB short of being exactly 2 GB. The 4-MB difference exists because the system never lets an application gain access to the 4-MB partition from 0x00000000 through 0x003FFFFF.

The last member, dwAvailVirtual (shown as AvailVirtual), is the only member of the structure specific to the process calling GlobalMemoryStatus—all the other members apply to the system and would be the same regardless of which process was calling GlobalMemoryStatus. To calculate this value, GlobalMemoryStatus adds up all of the free regions in the calling process's address space. The dwAvailVirtual value 2,136,846,336 indicates the amount of free address space that is available for VMStat to do with what it wants. If you subtract the dwAvailVirtual member from the dwTotalVirtual member, you'll see that VMStat has 10,506,240 bytes reserved in its virtual address space.

There is no member that indicates the amount of physical storage currently in use by the process.

Figure 14-2. The VMStat application

VMStat.cpp

 /****************************************************************************** Module: VMStat.cpp Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #include "..\CmnHdr.h" /* See Appendix A. */ #include <windowsx.h> #include <tchar.h> #include <stdio.h> #include "Resource.h" /////////////////////////////////////////////////////////////////////////////// // The update timer's ID #define IDT_UPDATE 1 /////////////////////////////////////////////////////////////////////////////// BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { chSETDLGICONS(hwnd, IDI_VMSTAT); // Set a timer so that the information updates periodically. SetTimer(hwnd, IDT_UPDATE, 1 * 1000, NULL); // Force a timer message for the initial update. FORWARD_WM_TIMER(hwnd, IDT_UPDATE, SendMessage); return(TRUE); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnTimer(HWND hwnd, UINT id) { // Initialize the structure length before calling GlobalMemoryStatus. MEMORYSTATUS ms = { sizeof(ms) }; GlobalMemoryStatus(&ms); TCHAR szData[512] = { 0 }; _stprintf(szData, TEXT("%d\n%d\n%I64d\n%I64d\n%I64d\n%I64d\n%I64d"), ms.dwMemoryLoad, ms.dwTotalPhys, (_ _int64) ms.dwAvailPhys, (_ _int64) ms.dwTotalPageFile, (_ _int64) ms.dwAvailPageFile, (_ _int64) ms.dwTotalVirtual, (_ _int64) ms.dwAvailVirtual); SetDlgItemText(hwnd, IDC_DATA, szData); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: KillTimer(hwnd, IDT_UPDATE); EndDialog(hwnd, id); break; } } /////////////////////////////////////////////////////////////////////////////// INT_PTR WINAPI Dlg_Proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand); chHANDLE_DLGMSG(hwnd, WM_TIMER, Dlg_OnTimer); } return(FALSE); } /////////////////////////////////////////////////////////////////////////////// int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) { DialogBox(hinstExe, MAKEINTRESOURCE(IDD_VMSTAT), NULL, Dlg_Proc); return(0); } //////////////////////////////// End of File ////////////////////////////////// 

VMStat.rc

 //Microsoft Developer Studio generated resource script. // #include "Resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "Resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_VMSTAT DIALOG DISCARDABLE 60, 60, 132, 66 STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "VMStat" FONT 8, "MS Sans Serif" BEGIN LTEXT "Memory load:\nTotalPhys:\nAvailPhys:\nTotalPageFile:\n\ AvailPageFile:\nTotalVirtual:\nAvailVirtual:", IDC_STATIC,4,4,51,56 RTEXT "Memory load:\nTotalPhys:\nAvailPhys:\nTotalPageFile:\n\ AvailPageFile:\nTotalVirtual:\nAvailVirtual:", IDC_DATA,60,4,68,56 END ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_VMSTAT ICON DISCARDABLE "VMStat.Ico" ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_VMSTAT, DIALOG BEGIN RIGHTMARGIN, 108 BOTTOMMARGIN, 65 END END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED 



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net