如何测量 32 位程序中 64 位进程的内存使用情况?
Posted
技术标签:
【中文标题】如何测量 32 位程序中 64 位进程的内存使用情况?【英文标题】:How can I measure memory usage of 64-bit process in 32-bit program ? 【发布时间】:2017-01-23 10:36:38 【问题描述】:我正在尝试从 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
。有没有其他方法可以测量进程内存使用情况,对它所构建的架构不敏感?
【问题讨论】:
从 64 位进程执行此操作,而不是从模拟器内部执行此操作 正如这里已经提到的:***.com/questions/15574638/…,结构中字段的大小由调用进程的位数定义,如果测量的进程是 x86-64 则可能发生溢出。所以使用 x86-64 进程进行测量。您可以编写一个“代理”应用程序,仅测量 x86-64 的内存使用情况,然后将值传递给原始 x86 进程(通过远程处理或任何其他 IPC)。 唉,有时候面对不切实际的限制,你只能放弃。 当然,WMI 使用外部 64 位进程完成它。在禁用 WMI 的机器上不起作用,这确实发生了。而且速度非常慢。但如果它符合您的要求,那就太好了。 嗯,它在某些机器上根本不起作用。如果可能,我希望避免使用 WMI 并使用 64 位进程。 Out of proc com 是一种方法,可以让您的主应用程序保持 32 位。工作集大小可能不是衡量内存使用情况的正确方法。 【参考方案1】:我找到了答案,可以使用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;
它工作得很好。
【讨论】:
以上是关于如何测量 32 位程序中 64 位进程的内存使用情况?的主要内容,如果未能解决你的问题,请参考以下文章
boost::interprocess 32 位和 64 位进程之间的共享内存