如何在Linux中禁用OOM Killer?

11

我的当前配置如下:

> cat /proc/sys/vm/panic_on_oom
0
> cat /proc/sys/vm/oom_kill_allocating_task
0
> cat /proc/sys/vm/overcommit_memory
1

但是当我运行一个任务时,它总是被杀掉。

> ./test/mem.sh
Killed
> dmesg | tail -2
[24281.788131] Memory cgroup out of memory: Kill process 10565 (bash) score 1001 or sacrifice child
[24281.788133] Killed process 10565 (bash) total-vm:12601088kB, anon-rss:5242544kB, file-rss:64kB

更新

我的任务用于科学计算,需要大量的内存,似乎将overcommit_memory=1设置为最佳选择。

更新2

实际上,我正在进行一个数据分析项目,需要超过16G的内存,但是被要求将其限制在约5G左右。可能无法通过优化程序本身来实现此要求,因为该项目使用了许多子命令,并且大多数命令不包含像Java中的XmsXmx选项。

更新3

我的项目应该是一个过度分配内存的系统。正如a3f所说,当内存分配失败时,我的应用程序似乎更愿意通过xmalloc崩溃。

> cat /proc/sys/vm/overcommit_memory
2
> ./test/mem.sh
./test/mem.sh: xmalloc: .././subst.c:3542: cannot allocate 1073741825 bytes (4295237632 bytes allocated)

虽然经历了许多可怕的考验使我感到筋疲力尽,但我不想放弃。请向我展示通往光明的道路;)


我刚发现这个链接:“如何配置Linux的内存杀手” https://www.oracle.com/technical-resources/articles/it-infrastructure/dev-oom-killer.html 我很高兴接受的答案链接到了文档,但我认为一个完整的教程/指南会更有帮助。 - PJ Brunet
由于您标记了“docker”,限制内存资源的最佳方式是使用docker / compose / k8s。只需查看文档,取决于您使用的docker编排机制,例如在docker-compose中,mem_limit - RodolfoAP
2个回答

14
The OOM killer无法离开。如果没有内存,就必须付出代价。你可以设置一个限制,以便在内存分配失败之后停止。将vm.overcommit_memory设置为2就能实现这一点。
文档中得知:
Linux内核支持以下超额承诺处理模式: 2-不超额承诺。系统的总地址空间提交量不能超过交换+可配置数量(默认为物理RAM的50%)。根据您使用的数量,在大多数情况下,这意味着在访问页面时进程不会被杀死,但会按适当方式收到有关内存分配的错误。
通常,内核会愉快地提供虚拟内存(超额承诺)。只有当您引用一个页面时,内核才必须将该页面映射到真正的物理帧上。如果它无法提供该请求,则需要通过OOM killer杀死进程以腾出空间。
禁用过度承诺意味着,例如malloc(3)将返回NULL,如果内核无法承诺请求的内存量。这使事情变得更加可预测,尽管有限(许多应用程序分配比它们所需的更多)。

谢谢!我的任务总是占用很多内存。如果设置overcommit_memory = 2,任务会暂停吗?这对于科学计算任务来说并不好,也许不应该这样做。 - Yang
1
@Yang 请查看我发布的链接。您可以设置一个上限,超过这个上限后分配将失败。然后,您的应用程序就必须处理内存分配失败。许多应用程序只会崩溃(通过空指针引用隐式地或通过例如“xmalloc”显式地)。我不知道您的应用程序如何处理它。 - a3f
1
@Yang 要么重写应用程序以消耗更少的内存,要么增加物理内存。第二个选项可能更便宜。 - a3f
1
@workless 这取决于内存超额许可策略,请查看链接的文档以获取更多信息。即使使用默认的超额许可行为,malloc(-1)也会返回NULL - a3f
@a3f 谢谢,我之前没有意识到这个问题。有很多程序甚至不检查返回地址,让我们小心禁用过度提交。 - davide
显示剩余4条评论

3
可能的oom_adj值范围为-17到+15。得分越高,相关进程被OOM-killer杀死的可能性就越大。如果将oom_adj设置为-17,则不考虑该进程进行OOM-killing。
但是,增加内存是更好的选择,如果增加内存不可能,则添加交换内存。
要增加交换内存,请尝试this link

2
请不要发布基本上只包含链接的答案。在你的答案中包括重要的要点,把链接作为额外信息或参考资料。 - glennsl
@glennsl 谢谢。 - Ravipati Praveen
@glennsl,感谢您提供的信息和链接。我已经更新了我的帖子。 - Ravipati Praveen
@RavipatiPraveen,非常感谢!禁用OOM杀掉进程确实是我想要的,将oom_adj设置为-17即可。增加交换空间听起来很不错,也许可以解决问题。我晚些时候会尝试一下,谢谢! - Yang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接