【问题标题】:GetProcessMemoryInfo PROCESS_MEMORY_COUNTERS_EX.PrivateUsage always 0GetProcessMemoryInfo PROCESS_MEMORY_COUNTERS_EX.PrivateUsage 始终为 0
【发布时间】:2015-12-18 08:02:08
【问题描述】:

我正在使用GetProcessMemoryInfo 函数通过其 PID 确定进程内存使用情况。

使用常规 PROCESS_MEMORY_COUNTERS 一切正常,但我需要 PrivateUsage 成员,该成员仅存在于扩展结构 PROCESS_MEMORY_COUNTERS_EX 中。

有几个文档促使我将扩展类型强制转换为基本类型,否则我的示例将无法编译。

我仍然能够从基本成员那里获得价值,例如 PeakWorkingSetSize,但 PrivateUsage 始终为 0。 我什至尝试重新定义 PSAPI_VERSION - 仍然没有。程序无法使用 PSAPI_VERSION

这是我的例子。

#include <windows.h>                      
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>

void _tmain (int argc, TCHAR *argv[])
{
    // use first argument as PID
    DWORD processID = strtol(argv[1],0, 0);
    HANDLE hProcess = OpenProcess(
        PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | SYNCHRONIZE,
        FALSE,
        processID);
    PROCESS_MEMORY_COUNTERS_EX pmc;
    ZeroMemory(&pmc, sizeof(PROCESS_MEMORY_COUNTERS_EX));
    // wait until process is dead
    WaitForSingleObject( hProcess , INFINITE );

    GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc) );
    fprintf(stdout, "  PeakWorkingSetSize : %d\n", pmc.PeakWorkingSetSize);
    fprintf(stdout, "  PrivateUsage : %d\n", pmc.PrivateUsage);
    CloseHandle(hProcess);
}

我执行notepad.exe,然后我把它的PID放到上面的程序中,毕竟我关闭记事本并寻找结果但PrivateUsage为零=(:

C:\utils>simple.exe 45656
  PeakWorkingSetSize : 6377472
  PrivateUsage : 0

C:\utils>

有什么建议为什么会发生?

C:\utils>cl --version
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

在 WIN7x64 上运行。

【问题讨论】:

  • 嘿@zamuka 你有什么解决办法吗?
  • 不。我放弃了,进入了 JavaScript 领域 =(
  • 听到这个消息很难过。将扩展类型转换为基本类型对我有用。

标签: c windows memory process


【解决方案1】:

我知道这是一个相当古老的问题,您可能不需要答案。但你非常接近。您在进程关闭后要求私有集内存,因此不再存在的进程没有内存。因此,Private Usage 为 0。

在我看来,您应该在固定时间间隔后请求私有集内存,直到进程终止。如果您将间隔保持在非常低的水平(例如 1 毫秒),您可能已经获得了进程的近端内存。

例子:

PROCESS_MEMORY_COUNTERS_EX pmc;
ZeroMemory(&pmc, sizeof(PROCESS_MEMORY_COUNTERS_EX));

//do for every millisecond until process terminates
do
{
  ZeroMemory(&pmc, sizeof(PROCESS_MEMORY_COUNTERS_EX));
  GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc) );

}while(WaitForSingleObject( hProcess , 1));

// wait until process is dead
// WaitForSingleObject( hProcess , INFINITE );
// GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc) );
fprintf(stdout, " PeakWorkingSetSize : %d\n", pmc.PeakWorkingSetSize);
fprintf(stdout, " PrivateUsage (Bytes): %d\n", pmc.PrivateUsage);
fprintf(stdout, " PrivateUsage (KB) : %f\n",(float)pmc.PrivateUsage/1024.0);
CloseHandle(hProcess);

进行上述更改后。将获得以下输出

C:\>PidMemory.exe 3456
 PeakWorkingSetSize : 12427264
 PrivateUsage (Bytes): 2269184
 PrivateUsage (KB) : 2216.000000

这有时可能会给出零,因为在某些情况下,进程已在 while 条件检查后终止。因此,给出 0。一个体面的工作是保留 PrivateUsage 的历史。

例子,

int history=0;
do
{
          ZeroMemory(&pmc, sizeof(PROCESS_MEMORY_COUNTERS_EX));
          GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc) );
          if(pmc.PrivateUsage != 0)
              history = pmc.PrivateUsage;
}while(WaitForSingleObject( hProcess , 1));

希望我对你有用。

【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2014-01-09
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    相关资源
    最近更新 更多