有没有办法配置 Linux OOM Killer 来杀死父进程而不是子进程?当子进程被杀死时,父进程继续以不良状态运行。我可以检测子进程是否被杀死,然后退出,但我想知道是否有办法告诉 OOM 杀手杀死父进程而不是牺牲子进程。
答案1
您可以通过更改虚拟文件中的值来调整任何给定进程被选为 OOM Killer 受害者的概率/proc/<pid>/oom_score_adj
。该值越接近 1000,该进程被 OOM Killer 选择的可能性就越大。
OOM Killer 用于选择受害者的逻辑在许多不同的内核版本中都发生了变化。现代内核版本更喜欢默认杀死子进程,因为通常的错误情况是 Web 服务器启动工作进程,如果出现错误,单个工作进程会失去控制并开始消耗内存,最好的纠正措施是杀死子进程并假设父进程在注意到子进程被杀死时可以处理这种情况。对于 Apache,它只会记录给定子进程的失败并继续运行。另一方面,PostgreSQL(看起来与 Linux 内核的 Apache 非常相似!)会注意到子进程被杀死,并且也会自动杀死所有其他子进程,并重新启动父进程以确保完整的系统状态完全知道。在这两种情况下,杀死唯一的父进程都不会产生更好的结果。具有多个选项卡的 Google Chrome(每个选项卡作为单独的子进程运行)的工作原理类似,一个选项卡耗尽 RAM 不应导致整个浏览器崩溃。
问题在于oom_score_adj
,它不是 OOM 杀手选择逻辑的乘数,而是针对进程计算的总系统 RAM 的额外千分之一。例如,如果您有 32 GB RAM,并且 Chrome 选项卡的oom_score_adj
值为 300(由 Google Chrome 主机进程自动设置),并且该选项卡实际上消耗 105 MB RAM,那么它肯定会被选为 OOM 受害者,因为当 OOM 杀手启动时选择受害者后,内核 OOM 杀手实现当前将该 Chrome 子项的“逻辑内存使用量”计算为 105 MB + 300/1000 * 32 GB = 9705 MB。显然,系统不会通过终止该进程来释放 9.7 GB RAM,但除非您有更大的进程,否则它仍然会被选择。