在进程被 OOM 杀手 / cgroup 杀死之前接收信号

Alb*_*ert 15 kill limit cgroups out-of-memory

在我们的集群中,我们限制了我们的进程资源,例如内存 ( memory.limit_in_bytes)。

我认为,这最终也是通过 Linux 内核中的 OOM 杀手来处理的(通过阅读源代码看起来是这样)。

有没有办法在我的进程被杀死之前获得信号?(就像SGE 的-notify选项一样,它将在进程终止qsubSIGUSR1之前发送。)

我在/dev/mem_notify 这里读到,但我没有 - 现在还有别的东西吗?我也读过这似乎有些相关。

我希望能够至少转储一个小的堆栈跟踪和其他一些有用的调试信息 - 但也许我什至可以通过释放一些内存来恢复。

我目前使用的一种解决方法是这个小脚本,它经常检查我是否接近 (95%) 限制,如果是,它会向进程发送一个SIGUSR1. 在 Bash 中,我在后台 ( cgroup-mem-limit-watcher.py &) 中启动此脚本,以便它监视同一 cgroup 中的其他 proc,并在父 Bash 进程终止时自动退出。

小智 10

当 cgroup 的内存使用量超过阈值时,可以注册通知。原则上,将阈值设置在低于实际限制的合适点可以让您发送信号或采取其他行动。

看:

https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt


Jul*_*ier 7

OOM 杀手确实发送了 SIGKILL,否则让有问题的程序选择继续会适得其反。

这意味着一个进程绝对没有办法知道它什么时候会被它杀死。

管理此类问题通常意味着对程序或其配置进行更正。有时,根据系统的配置,简单地增加交换空间可以为操作系统提供更大的内存管理灵活性,以避免采取此类激烈措施。


小智 5

看起来您已经使用了 cgroup,这有帮助。

如果您的进程是 cgroup 中唯一的进程(即唯一可以被杀死的进程)并且您拥有您执行的程序,那么您可以修改您的程序以生成子进程,并将其 oom 分数调整为某个高值。因此,这个进程将成为一个诱饵:当你达到 cgroup 内存限制时,OOM Killer 将杀死这个诱饵进程而不是主进程。主进程可以等待其子诱饵来了解 OOM 杀手被触发的确切时刻。

IMO,它比具有一定阈值的监视脚本更容易。这是 Bash 中的示例

#!/usr/bin/bash

self_pid=$$

(
    /usr/bin/sleep infinity &
    oom_decoy_pid=$!
    echo "1000" > "/proc/${oom_decoy_pid}/oom_score_adj"
    echo "Launched oom decoy ${oom_decoy_pid} for parent process ${self_pid}"

    wait $oom_decoy_pid

    echo "OOM decoy is killed. Likely OOM is coming!"
    echo "Signalling parent..."
    kill -SIGTERM $self_pid
)&

while true; do
    sleep 1
    echo "Doing something important and memory heavy"
done
Run Code Online (Sandbox Code Playgroud)