我知道可以通过限制单个用户的进程数来防止 fork 炸弹,并且内存泄漏不会冻结我的操作系统,因为 Linux 有 OOM 杀手。但是内存泄漏的 fork 炸弹怎么办?
#include <vector>
#include <unistd.h>
#include <ctime>
#include <cstdlib>
using namespace std;
int main() {
srand(time(NULL));
vector<int> vec;
do {
try {
for (int i=0; i<10000000; i++)
vec.push_back(rand());
} catch (bad_alloc e) {
}
fork();
} while (1);
return 0;
}
尝试此代码后,我的 Linux 被冻结了。有什么办法可以防止它冻结吗?
此代码在 Archlinux、Linux 4.0.5 上进行了测试
使用此命令编译代码:
g++ -o test test.cpp
更多信息:由于代码只需分叉几次就能耗尽我的所有内存,因此它不像普通的 fork 炸弹,限制进程数也没用。此外,fork() 执行频繁(当内存不足时),因此 OOM-killer 比 fork 慢得多。因此,我必须使用 Alt-SysRq-REI 来停止这些进程,但这不是我想要的。
这是我第一次在 SuperUser 上提问。如果我的问题不合适,请帮助我。谢谢你的帮助。
答案1
它不一定是内存泄漏的 fork 炸弹 - 甚至,例如,中等代码大小上的一个make -j
(或具有太高的j
系数)或任何产生一堆后代(少于活跃用户的合理限制)的进程,每个进程本身都会消耗大量内存,但这些内存太小而无法成为 OOM 杀手的目标(或者在被 OOM 杀手击中时无法提供显着的缓解)可能会产生类似的效果。
可以编写自定义监控脚本/工具(由 root 以高优先级执行),它可以监视此类进程生成模式,并在必要时通过 pgid 或 userid 终止它们(即同时终止,而不是像 OOM 终止程序那样逐个终止),以免它们对系统造成致命影响。合理的生成/资源消耗率,但我不确定是否可能只是任何率。