我试图在C ++中测量来自32位进程的64位应用程序的进程内存使用情况(WorkingSetSize
)。我尝试使用Toolhelp
:
void GetProcMemoryInfo(const wchar_t * procName)
{
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (wcscmp(entry.szExeFile, procName) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
PROCESS_MEMORY_COUNTERS objProcessMemoryInfo;
if (GetProcessMemoryInfo(hProcess, &objProcessMemoryInfo, sizeof(objProcessMemoryInfo)))
{
wchar_t szProcessMemoryInfo[100];
wsprintf(szProcessMemoryInfo, L"Working Set Bytes (MB): %d\n", objProcessMemoryInfo.WorkingSetSize / (1024 * 1024));
OutputDebugString(szProcessMemoryInfo);
}
CloseHandle(hProcess);
}
}
}
CloseHandle(snapshot);
}
此解决方案工作正常,但前提是它构建为x64
应用程序。否则 - 我得到2^32
的最大值。我想的情况是PROCESS_MEMORY_COUNTERS
在内部使用SIZE_T
。有没有其他方法来衡量进程内存使用情况,对它构建的体系结构不敏感?
答案 0 :(得分:0)
我找到了答案,可以使用Windows Management Instrumentation
:
class WMI
{
public:
WMI();
~WMI();
HRESULT Open(LPCTSTR machine=NULL, LPCTSTR user=NULL, LPCTSTR pass=NULL);
void Close();
HRESULT GetProcStringProperty(DWORD pid, TCHAR *name, TCHAR *value, DWORD len);
int GetLastError();
private:
IWbemServices *wbem;
HRESULT result;
BSTR GetProcQuery(DWORD pid);
};
使用以下函数检索属性值:
HRESULT WMI::GetProcStringProperty(DWORD pid, TCHAR *name, TCHAR *value, DWORD len)
{
IWbemClassObject *obj;
VARIANT var;
result = wbem->GetObject(GetProcQuery(pid), 0, 0, &obj, 0);
if (FAILED(result)) {
return result;
}
result = obj->Get(name, 0, &var, 0, 0);
if (SUCCEEDED(result)) {
if (var.vt == VT_NULL) {
result = E_INVALIDARG;
}
else {
lstrcpyn(value, var.bstrVal, len);
}
VariantClear(&var);
}
obj->Release();
return result;
}
使用以下函数检索内存使用量值:
int wmiGetMemProc(uint64_t pid, uint64_t *procmem)
{
int status;
TCHAR buf[MEM_MAX];
WMI *wmi = new WMI();
if (FAILED(wmi->Open())) {
return wmi->GetLastError();
}
if (FAILED(wmi->GetProcStringProperty(pid, L"WorkingSetSize", buf, MEM_MAX))) {
status = wmi->GetLastError();
}
else {
*procmem = _wcstoui64(buf, NULL, 10);
}
wmi->Close();
delete wmi;
return status;
}
它运作得很好。