如何在Windows上进行系统或库调用以了解运行C程序的程序的内存使用情况?
答案 0 :(得分:2)
很大程度上取决于您对该程序使用的内存的含义。仅举一个明显的例子,Windows DLL几乎映射到所有程序的地址空间。你是否考虑过程序使用的内存?如果您有两个(或更多)程序实例正在运行,那么它自己的可执行文件(以及任何DLL)通常也会映射到所有这些进程。同时,其中很多可能只是地址空间 - 未使用的代码可能根本无法加载到物理内存中。
所有这一切,这是一个程序,它将遍历指定进程的内存块并转储有关它们的信息。根据流程使用的内存的含义,您可以(例如)查找标记为Private
的块。
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
unsigned long usage;
void show_modules(HANDLE process) {
unsigned char *p = NULL;
MEMORY_BASIC_INFORMATION info;
for ( p = NULL;
VirtualQueryEx(process, p, &info, sizeof(info)) == sizeof(info);
p += info.RegionSize )
{
printf("%#10.10x (%6uK)\t", info.BaseAddress, info.RegionSize/1024);
switch (info.State) {
case MEM_COMMIT:
printf("Committed");
break;
case MEM_RESERVE:
printf("Reserved");
break;
case MEM_FREE:
printf("Free");
break;
}
printf("\t");
switch (info.Type) {
case MEM_IMAGE:
printf("Code Module");
break;
case MEM_MAPPED:
printf("Mapped ");
break;
case MEM_PRIVATE:
printf("Private ");
}
printf("\t");
if ((info.State == MEM_COMMIT) && (info.Type == MEM_PRIVATE))
usage +=info.RegionSize;
int guard = 0, nocache = 0;
if ( info.AllocationProtect & PAGE_NOCACHE)
nocache = 1;
if ( info.AllocationProtect & PAGE_GUARD )
guard = 1;
info.AllocationProtect &= ~(PAGE_GUARD | PAGE_NOCACHE);
switch (info.AllocationProtect) {
case PAGE_READONLY:
printf("Read Only");
break;
case PAGE_READWRITE:
printf("Read/Write");
break;
case PAGE_WRITECOPY:
printf("Copy on Write");
break;
case PAGE_EXECUTE:
printf("Execute only");
break;
case PAGE_EXECUTE_READ:
printf("Execute/Read");
break;
case PAGE_EXECUTE_READWRITE:
printf("Execute/Read/Write");
break;
case PAGE_EXECUTE_WRITECOPY:
printf("COW Executable");
break;
}
if (guard)
printf("\tguard page");
if (nocache)
printf("\tnon-cachable");
printf("\n");
}
}
int main(int argc, char **argv) {
int pid;
if (argc != 2) {
fprintf(stderr, "Usage: %s <process ID>", argv[0]);
return 1;
}
sscanf(argv[1], "%i", &pid);
HANDLE process = OpenProcess(
PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
false,
pid);
show_modules(process);
printf("Total memory used: %luKB\n", usage/1024);
return 0;
}
答案 1 :(得分:0)
使用GetProcessMemoryInfo
:
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
// To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS
// and compile with -DPSAPI_VERSION=1
void PrintMemoryInfo( DWORD processID )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Print information about the memory usage of the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
return;
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
printf( "\tPeakWorkingSetSize: 0x%08X\n",
pmc.PeakWorkingSetSize );
printf( "\tWorkingSetSize: 0x%08X\n", pmc.WorkingSetSize );
printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakPagedPoolUsage );
printf( "\tQuotaPagedPoolUsage: 0x%08X\n",
pmc.QuotaPagedPoolUsage );
printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakNonPagedPoolUsage );
printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaNonPagedPoolUsage );
printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
printf( "\tPeakPagefileUsage: 0x%08X\n",
pmc.PeakPagefileUsage );
}
CloseHandle( hProcess );
}
int main( void )
{
// Get the list of process identifiers.
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
{
return 1;
}
// Calculate how many process identifiers were returned.
cProcesses = cbNeeded / sizeof(DWORD);
// Print the memory usage for each process
for ( i = 0; i < cProcesses; i++ )
{
PrintMemoryInfo( aProcesses[i] );
}
return 0;
}
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682050(v=vs.85).aspx