此问题在此处已有答案:
How to get available memory C++/g++?(10个答案)
7天前关闭
截至6天前,社区正在审查是否重新讨论这个问题。
为什么我运行这个程序时会被“杀死”?
#include <stddef.h>
int main() {
constexpr size_t N{5'000'000'000};
unsigned int *bigdata;
bigdata = new unsigned int[N];
for (size_t i=0; i<N; i++)
bigdata[i] = i;
return 0;
}
字符串
将N
设置为更大的值(如50'000' 000 '000)将生成std::bad_alloc
。使用较小的值(如1'000'000' 000),程序工作正常。但是对于5'000'000' 000,它在写入数组时会非常不可预测地失败,突然在控制台上打印“Killed”并退出代码137。有没有办法知道在给定的系统上使用多大的数组是安全的?
附加信息
有人将这个问题标记为多余,链接到How to get available memory C++/g++?。这不是不可想象的,这个问题已经回答了,但链接的页面不是它。使用最高评级答案中提供的代码示例仍然会生成相同的错误。以下是完整的程序:
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
unsigned long long getTotalSystemMemory() {
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
return pages * page_size;
}
int main() {
size_t N = getTotalSystemMemory();
printf("Size: %zu \n", N);
unsigned int *bigdata = (unsigned int *)malloc(N);
for (size_t i = 0; i < N / sizeof(unsigned int) - 1; i++)
bigdata[i] = i;
return 0;
}
型
输出:
Size: 16'439'369'728 // Separators added manually
Killed
型
1条答案
按热度按时间kh212irz1#
Linux内核向进程发送SIGKILL的一个原因是,如果进程使用了太多内存,它将终止该进程。更具体地,这些是一些可能的情况:
有趣的是,man page mmap(2)文档中的SIGSEGV而不是SIGKILL。
在man proc(5)中搜索 /proc/sys/vm/overcommit_memory,以获取有关如何在Linux上禁用或配置过度提交的文档。
要测试它,请运行您的进程,并在进程收到SIGKILL后快速运行
dmesg
。dmesg
内核日志输出中应该会显示一些OOM杀手消息。要进一步测试它,运行sudo sysctl -w vm.oom-kill = 0
禁用OOM杀手,再次运行您的进程,如果SIGKILL没有发生,那么它就是OOM杀手(在禁用之前)。