无法使用GetProcessMemoryInfo测量静态数组内存使用情况

时间:2017-03-17 08:38:32

标签: c++ memory profiling ram measure

我正在尝试学习有关内存使用情况的详细信息,以及如何使用C ++进行测量。我知道在Windows下,当包括<Windows.h>时,检索当前应用程序进程使用的RAM量的快速方法是:

PROCESS_MEMORY_COUNTERS info;
GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
(uint64_t)info.WorkingSetSize;

然后,我用它来进行一个非常简单的测试:

#include <iostream>
#include <Windows.h>"

int main(void)
{
    uint64_t currentUsedRAM(0);

    PROCESS_MEMORY_COUNTERS info;
    GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
    currentUsedRAM = info.WorkingSetSize;

    const int N(1000000);
    int x[N]; //in the second run, comment this line out
    int y[N]; //in the second run, comment this line out
    //int *x = new int[N]; //in the second run UNcomment this line out
    //int *y = new int[N]; //in the second run UNcomment this line out
    for (int i = 0; i < N; i++)
    {
        x[i] = 1;
        y[i] = 2;
    }

    GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
    currentUsedRAM = info.WorkingSetSize - currentUsedRAM;

    std::cout << "Current RAM used: " << currentUsedRAM << "\n";

    return 0;
}

当我运行上面的代码时,我完全不明白,输出是:Current RAM used: 0,而我期待大约8mb的东西,因为我填充了两个100万个条目的1D int数组每。现在,如果我重新运行代码但使xy成为dinamically分配的数组,现在输出正如预期的那样:Current RAM used: 8007680

为什么?如何在两种情况下检测内存使用情况?

1 个答案:

答案 0 :(得分:0)

编译器已优化您的代码。事实上,对于你的第一次运行,没有分配x或y。考虑到可见的副作用:GetProcessMemoryInfo的返回值,这种优化似乎有点奇怪。

无论如何,您可以通过添加一些其他副作用来防止这种情况,例如输出这两个数组中每个元素的总和,这将会导致崩溃。

为具有自动存储持续时间的本地对象分配内存at the beginning of the enclosing code block and deallocated at the end 。所以你的代码无法测量main中任何自动sotrage持续时间变量的内存使用量(也不是我删除的代码片段,我不知道)。但是对于那些具有动态存储持续时间的对象,情况有所不同,它们是按请求分配的。

我设计了一个测试,其中包含对评论区域中讨论的回忆。如果程序更深入,您可以看到内存使用量增加。这证明它计算堆栈上的memroy用法。顺便说一句,它不计算你的对象需要多少内存,而是你的程序需要多少。

void foo(int depth, int *a, int *b, uint64_t usage) {
  if (depth >= 100)
    return ;
  int x[100], y[100];

  for (int i = 0; i < 100; i++)
  {
    x[i] = 1 + (a==nullptr?0:a[i]);
    y[i] = 2 + (b==nullptr?0:b[i]);
  }

  PROCESS_MEMORY_COUNTERS info;
  GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));

  std::cout << "Current RAM used: " << info.WorkingSetSize - usage << "\n";

  foo(depth+1,x,y,usage);

  int sum = 0;
  for (int i=0; i<100; i++)
    sum += x[i] + y[i];

  std::cout << sum << std::endl;
}

int main(void)
{
  uint64_t currentUsedRAM(0);
  PROCESS_MEMORY_COUNTERS info;
  GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
  currentUsedRAM = info.WorkingSetSize;

  foo(0, nullptr, nullptr, currentUsedRAM);

  return 0;
}

/*
Current RAM used: 0
Current RAM used: 61440
Current RAM used: 65536
Current RAM used: 65536
Current RAM used: 65536
Current RAM used: 65536
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 69632
Current RAM used: 73728
*/

系统每次分配4k,这是页面的大小。我不知道它为什么会出现0,然后突然变成61440.解释windows如何管理内存是非常困难的,并且远远超出了我的能力,尽管我对4k的东西有信心......并且它确实计算了内存使用量对于具有自动存储持续时间的变量。