无法测量由 std::vector<>::reserve under Windows 引起的内存分配

Can't measure memory allocation caused by std::vector<>::reserve under Windows

考虑以下代码片段:

void OutputMemoryStatus()
  {
  PROCESS_MEMORY_COUNTERS pmc;
  GetProcessMemoryInfo(::GetCurrentProcess(), &pmc, sizeof(pmc));
  std::cout << pmc.WorkingSetSize / (1024.0 * 1024.0) << std::endl;
  }

int main()
  {
  std::vector<int> vec;
  OutputMemoryStatus();
  vec.reserve(100'000'000);
  OutputMemoryStatus();
  std::cout << vec.capacity() << std::endl;
  for (int i = 0; i < 1'000'000; ++i)
    vec.push_back(i);
  OutputMemoryStatus();
  }

输出如下:

Memory used: 3.11328
Memory used: 3.20703
Capacity: 100000000
Memory used: 7.03516

所以看起来尽管保留了 400 MB 的内存,这已通过调用 capacity() 得到确认,Windows 并不认为此内存已分配,但当我们实际填充时具有 1'000'000 个值的向量,该内存 (4MB) 被视为已分配。

如何解释?

我正在使用 Visual Studio 2015,发布配置,x86 平台。

更新

现在编译器不知道实际使用的内存量,但是如果我输入 size = 1'000'000,结果和以前一样。

  int size;
  std::cin >> size;
  std::vector<int> vec;
  OutputMemoryStatus();
  vec.reserve(100'000'000);
  OutputMemoryStatus();
  std::cout << "Capacity: " << vec.capacity() << std::endl;
  for (int i = 0; i < size; ++i)
    vec.push_back(i);
  OutputMemoryStatus();

工作集是在任何给定时间实际位于物理 RAM 中的内存,并且随着内存页面的页面调入和调出而变化。内存,尤其是大的分配,可以从页面调出开始。使用它们会将它们调入,但可能会在此过程中调出其他内容。

PageFileSize 可能是对提交给进程的内存量的更好度量。

此外,不确定 Windows 是否这样做,但过度使用内存是一回事,如果发生这种情况,可能会导致 OS 终止您的程序或它认为合适的其他程序机器上的所有进程同时需要太多内存。