1 winapi
我在 CodeGear Builder 2009 中使用 Win32 C++ 目标是 Windows XP Embedded。
我找到了 PROCESS_MEMORY_COUNTERS_EX 结构,并且创建了一个简单的函数来返回进程的内存消耗
SIZE_T TForm1::ProcessPrivatBytes( DWORD processID )
{
SIZE_T lRetval = 0;
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS_EX pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
{
lRetval = 1;
}
else
{
if ( GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)) )
{
lRetval = pmc.WorkingSetSize;
lRetval = pmc.PrivateUsage;
}
CloseHandle( hProcess );
}
return lRetval;
}
//---------------------------------------------------------------------------
Run Code Online (Sandbox Code Playgroud)
我必须使用 lRetval = pmc.WorkingSetSize; 或lRetval = pmc.PrivateUsage;
privateUsage 是我在 perfmon 中看到的。但那个WorkingSetSize到底是什么?
当我分配它时,我要查看在计数器中分配的每个字节。这可能吗?
问候
杰夫德恩
这是一个比您可能意识到的更难的问题。原因是 Windows 在进程之间共享大多数可执行代码(尤其是构成 Windows 本身大部分的进程)。例如,通常会将 kernel32.dll 的一份副本加载到内存中,但它通常会映射到每个进程中。您是否考虑您的进程正在“使用”或没有使用的那部分内存?
私有内存是该特定进程所独有的。这也可能有些误导。由于您的进程的可执行文件可能会与另一个进程共享(即可以运行您的程序的两个实例),因此这不会被算作私有内存的一部分,即使(通常是这种情况)只有一个实例跑步。
工作集大小大约 99.999% 毫无意义。它返回的是进程的首选工作集大小。您可以使用 SetProcessWorkingSetSize() 进行调整。Windows 有一个工作集修剪器,可以尝试修剪工作集。如果内存可用,它会使用工作集大小来猜测是否值得尝试修剪此进程的工作集 - 即,如果其当前工作集大于设置的工作集大小,它会尝试将其缩小。否则,它(大部分)会不管它。
很可能你所做的任何事情都不会显示你分配的字节。调用 Windows 分配内存相当慢,因此通常所做的是运行时库从 Windows 分配相当大的内存块。当您分配内存时,运行时库会为您提供一大块内存的一部分。只有当该块消失时,它才会返回 Windows 并要求更多。