【发布时间】: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_arraysconst(或constexpr)轻松使其符合标准 -
@knopers8 通过使用诸如 VLA 之类的扩展(编译器希望以任何方式实现它们),您需要更改为有效的 C++ 并重新运行测试。
-
感谢您的指出!不过,我没有在测试中使用它,这只是说明问题的一个小例子。
标签: c++ linux memory-management