此代码在命令行中输入一个数字作为输入,并多次调用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系统被冻结的情况下,该进程是否可以实际执行有用的工作?)
答案 0 :(得分:1)
为什么操作系统允许进程将内存接管到这种程度?
因为它被配置为这样做。
Linux内核支持POSIX.1-2008中标准化的每个进程资源限制等功能。见例如prlimit
用于命令行访问这些,getrlimit()/setrlimit()
用于C库接口。
在大多数Linux发行版中,这些限制由limits.conf中的可插入验证模块pam_limits设置。
问题是,这些限制是特定于任务的。它们在不同系统之间变化很大,甚至从用户到用户也是如此:有些人不喜欢他们的系统开始寻呼(像OP描述的那样慢下来),而且宁愿过程失败;其他人宁愿等待一段时间,因为他们实际上需要资源匮乏过程的结果。设置限制是系统管理员的责任。
我想可以轻松编写一个程序来检查当前配置(特别是/proc/meminfo
),并为单用户台式机/笔记本电脑设置资源限制。但是,你也可以创建一个帮助脚本,比如/usr/local/bin/run-limited
,
#!/bin/sh
exec prlimit --as=1073741824 --rss=262144 "$@"
因此您可以运行任何地址空间限制为1 GB且常驻设置大小(实际使用的RAM数量)为256k页的程序。