【发布时间】:2017-04-19 04:48:55
【问题描述】:
此代码在命令行中将一个数字作为输入,并多次调用 heapOverflow() 函数:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void heapOverflow()
{
unsigned *some_array = malloc(50000);
}
int main(int argc, char *argv[])
{
unsigned num_calls = atoi(argv[1]);
while (num_calls > 0)
{
heapOverflow();
num_calls--;
}
return 0;
}
在 Linux Mint 17.1 上,使用足够大的输入(例如,在我的情况下为 10000000)运行此程序会使系统冻结几分钟,然后 bash 返回“Killed”,然后系统再缓慢运行几分钟。
为什么操作系统允许进程在这种程度上接管内存?当很明显它会请求太多堆内存时,调度程序和内存管理器不应该一起工作来杀死一个进程吗?或者是否存在将所有这些内存分配给一个进程可能有用的情况(即,即使系统的其余部分或至少 X GUI 系统被冻结,该进程实际上是否可以做有用的工作?)
【问题讨论】:
-
malloc不成功时返回NULL。请检查,这是必不可少的。 -
Linux内核允许内存过度提交(这样程序就可以请求比可用内存更多的内存,并且分配成功,但是当内存根本不可用时代码会崩溃) .在您最喜欢的搜索引擎上搜索“Linux OOM Killer”(内存不足杀手)。您的代码并没有真正使用它分配的内存;它需要很长时间才能用完,因为您必须用完指针的空间,而不是内存本身。如果您在分配内存后将其归零(可能使用
calloc()),您会更快崩溃,并且对系统的影响更小。 -
当一个进程实际上需要大量内存时,您认为应该发生什么?无论如何都应该被杀死吗?
-
@immibis 是的,我想我错误地将操作系统和发行版软件混为一谈。内核是否不需要关心进程的相对重要性,并且它“信任”程序员选择如何最好地使用内存?
-
@JonathanLeffler 感谢您的详细回答和参考!
标签: c linux memory-management operating-system heap-memory