2017-01-23 21 views
-1

私は、C++の32ビットプロセスからの64ビットアプリケーションのプロセスメモリ使用量(WorkingSetSize)を測定しようとしています。私はToolhelpを使用してみました:32ビットプログラムで64ビットプロセスのメモリ使用量を測定するにはどうすればよいですか?

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を使用していると思います。プロセスのメモリ使用量を測定する他の方法はありますか?

+1

エミュレータの内部からではなく、64ビットプロセスからこれを行います。 –

+0

@DavidHeffernan最終行は32ビットプロセスから行う必要があります。それを使用するアプリケーションは32ビットです。 – pSoLT

+1

ここに記載されているalredy:http://stackoverflow.com/questions/15574638/measuring-process-peak-memory-usage-post-mortem、構造体のフィールドのサイズは、htによって呼び出されるprocess'esのビット数と測定されたプロセスがx86-64である場合にオーバーフローが発生する可能性があります。したがって、x86-64プロセスを使用して測定を行います。 x86-64であるメモリの消費量を測定するだけの「プロキシ」アプリケーションを作成し、その値をリモートまたは他のIPC経由で元のx86プロセスに渡すことができます。 –

答えて

0

私は答えを発見し、それがWindows Management Instrumentationを使用して行うことができます。メモリ使用量の値は

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; 
} 

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); 
}; 

プロパティの値には、次の関数を使用して取得されます

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; 
} 

これはうまく動作します。

関連する問題