【问题标题】:Linux promises more memory than it can give [duplicate]Linux承诺比它所能提供的更多的内存[重复]
【发布时间】:2020-05-17 04:52:32
【问题描述】:

考虑以下在 Linux 上运行的小程序:

#include <iostream>
#include <unistd.h>
#include <cstring>

int main() {
  size_t array_size = 10ull * 1000 * 1000 * 1000;
  size_t number_of_arrays = 20;
  char* large_arrays[number_of_arrays];

  // allocate more memory than the system can give
  for (size_t i = 0; i < number_of_arrays; i++)
    large_arrays[i] = new char[array_size];

  // amount of free memory didn't actually change
  sleep(10);

  // write on that memory, so it is actually used
  for (size_t i = 0; i < number_of_arrays; i++)
    memset(large_arrays[i], 0, array_size);

  sleep(10);

  for (size_t i = 0; i < number_of_arrays; i++)
    delete [] large_arrays[i];

  return 0;
}

它分配了大量的内存,超过了系统所能提供的。但是,如果我使用top 监控内存使用情况,它实际上并没有减少。程序稍等片刻,然后开始写入分配的内存,然后可用的可用内存量下降......直到系统变得无响应并且程序被oom-killer杀死。

我的问题是:

  • 为什么 Linux 承诺分配比它实际提供的更多的内存? new[] 不应该在某个时候抛出std::bad_alloc 吗?
  • 我如何确保 Linux 实际上占用一块内存而无需写入它?我正在编写一些基准测试,我想快速分配大量内存,但同时,我需要保持在一定的内存限制以下。
  • 是否可以监控这个“承诺”内存的数量?

内核版本为3.10.0-514.21.1.el7.x86_64。也许它在新版本上的行为有所不同?

【问题讨论】:

  • char* large_arrays[number_of_arrays]; -- 这不是有效的 C++。
  • 这是只有g++才能理解的东西吗?它确实编译它。
  • @knopers8 是的,可变长度数组是 GCC 对 C++ 的扩展(它们是 C 中的一个特性)。但是,您可以通过设置number_of_arrays const(或constexpr)轻松使其符合标准
  • @knopers8 通过使用诸如 VLA 之类的扩展(编译器希望以任何方式实现它们),您需要更改为有效的 C++ 并重新运行测试。
  • 感谢您的指出!不过,我没有在测试中使用它,这只是说明问题的一个小例子。

标签: c++ linux memory-management


【解决方案1】:

为什么 Linux 承诺分配比它实际提供的更多的内存?

因为您的系统就是这样配置的。你可以改变行为。 sysctl 'vm.overcommit_memory'

new[] 不应该在某个时候抛出 std::bad_alloc 吗?

如果系统过度提交内存,则不会。

我如何确定 Linux 确实占用了一块内存而无需写入它?

据我所知,你不能。当访问未映射的内存时,Linux 在页面错误时映射内存。

是否可以监控这个“承诺”的内存量?

我认为您正在寻找进程内存的“虚拟”大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-04
    • 2014-12-09
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-01-29
    • 2019-02-04
    • 2015-04-26
    相关资源
    最近更新 更多