我知道在 Linux 上有一个称为“OOM Killer”的内核功能。当 OOM (Out-Of-Memory)情况消退时,是否有“进程复活”之类的东西?
我知道由于各种原因,这个功能很难实现,但是有什么可以接近它的吗?
编辑: 示例:“Resurrector”将保证有一块内存用于存储一组有限的进程信息(例如命令行、环境等)(即不是整个进程代码和数据!)。一旦 OOM 条件被清除,“Resurrector”可以通过列表并“复活”一些进程。
从我收集到现在,似乎没有类似于我所要求的功能。
我知道在 Linux 上有一个称为“OOM Killer”的内核功能。当 OOM (Out-Of-Memory)情况消退时,是否有“进程复活”之类的东西?
我知道由于各种原因,这个功能很难实现,但是有什么可以接近它的吗?
编辑: 示例:“Resurrector”将保证有一块内存用于存储一组有限的进程信息(例如命令行、环境等)(即不是整个进程代码和数据!)。一旦 OOM 条件被清除,“Resurrector”可以通过列表并“复活”一些进程。
从我收集到现在,似乎没有类似于我所要求的功能。
不,一旦一个进程被 OOM Killer 杀死,它就死了。您可以重新启动它(资源允许),如果它是由系统管理的东西(也许是通过 inittab),它可能会以这种方式重新启动。
编辑:作为一个思想实验,想想一个过程的复活意味着什么。即使您可以存储整个进程状态,您也不希望这样做,因为被杀死的进程可能是内存不足情况的原因。
所以最好的办法是存储它的启动状态(命令行等)。但这也不好,因为这可能是系统首先内存不足的原因!
此外,如果您以这种方式恢复进程,则不知道会出现什么问题。如果过程控制硬件怎么办?如果流程控制不应该多次运行怎么办?如果它连接到一个不再存在的 tty 怎么办(因为 sshd 是被杀死的进程之一)?
系统不可能知道的进程周围有大量的上下文。唯一明智的事情是内核所做的事情:杀死傻瓜并继续前进。
我想你可以想象一个休眠进程到磁盘的策略,但是鉴于我们的内存不足(包括交换),这意味着要么预先保留一些磁盘空间,要么决定在飞。任何一种策略都可能无法处理相关流程的规模。
简而言之:不,你不会从 OOM 杀手那里回来。这是一个杀手,你只需要处理它。
当然没有。否则,如果没有更多的内存来存储被杀死的进程,它可以存储在哪里?:-)
问题是,只有在所有可用内存(RAM 和磁盘交换内存)耗尽时,OOM 杀手才会发挥作用。如果“进程复活器”可以在条件消退后“复活”一个进程,那么它应该能够在“杀手”开始时将其存储在某个地方。但是由于杀手只在没有可用内存时启动,所以这是不可能的。
当然你可能会说“保存到磁盘”,但是,交换内存就是一个磁盘。如果您想限制进程的内存消耗,请使用功能并通过程序或文件系统ulimit
手动跟踪您的内存使用情况。“OOM 杀手”是一种恐慌措施,对进程来说应该不是很好。ps
/proc
您可以使用的示例ulimit
(也许没有,但我无法在我的系统 atm 上尝试 OOM 杀戮)
#!/bin/bash
save_something=$ENV_VARIABLE
( ulimit -Sv 1000000;
perl -e 'print "Taking all RAM!!!\n"; while (1) { $a[$i++] = $i; }'
)
echo "killed, resetting"
( ulimit -Sv 1000000;
export ENV_VARIABLE="$save_something"
perl -e 'print "Taking all RAM!!!\n"; while (1) { $a[$i++] = $i; }'
)