如何处理 Linux 上的内存泄漏 fork 炸弹?

如何处理 Linux 上的内存泄漏 fork 炸弹?

我知道可以通过限制单个用户的进程数来防止 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 终止程序那样逐个终止),以免它们对系统造成致命影响。合理的生成/资源消耗率,但我不确定是否可能只是任何率。

相关内容