我的应用程序在Linux上作为后台进程运行。它目前在终端窗口的命令行中启动。

最近,一个用户正在执行应用程序一段时间,它神秘地死亡了。文本:

杀了

在终端机上。这样发生了两次。我问是否有人在不同的终端使用kill命令杀死进程?不。

在什么情况下Linux会决定终止我的进程?我相信shell显示“已杀”是因为进程在接收到kill(9)信号后死亡。如果Linux发送了终止信号,系统日志中是否应该有一条消息解释为什么它被终止?


当前回答

让我先解释一下什么时候以及为什么调用OOMKiller ?

假设你有512内存+ 1GB交换内存。所以理论上,你的CPU总共可以访问1.5GB的虚拟内存。

现在,在总内存为1.5GB的情况下,一切运行正常。但是突然(或逐渐地),您的系统开始消耗越来越多的内存,它达到了总内存使用量的95%左右。

现在假设有任何进程向内核请求了大块内存。内核检查可用内存,发现无法为进程分配更多内存。因此,它将尝试调用/调用OOMKiller (http://linux-mm.org/OOM)来释放一些内存。

OOMKiller有自己的算法来为每个进程评分。通常,使用更多内存的进程将成为被杀死的受害者。

我在哪里可以找到OOMKiller的日志?

通常在/var/log目录下。/var/log/kern.log或/var/log/dmesg

希望这对你有所帮助。

一些典型的解决方案:

增加内存(不是交换) 找到程序中的内存泄漏并修复它们 限制任何进程可以使用的内存(例如,可以使用JAVA_OPTS限制JVM内存) 查看日志和谷歌:)

其他回答

让我先解释一下什么时候以及为什么调用OOMKiller ?

假设你有512内存+ 1GB交换内存。所以理论上,你的CPU总共可以访问1.5GB的虚拟内存。

现在,在总内存为1.5GB的情况下,一切运行正常。但是突然(或逐渐地),您的系统开始消耗越来越多的内存,它达到了总内存使用量的95%左右。

现在假设有任何进程向内核请求了大块内存。内核检查可用内存,发现无法为进程分配更多内存。因此,它将尝试调用/调用OOMKiller (http://linux-mm.org/OOM)来释放一些内存。

OOMKiller有自己的算法来为每个进程评分。通常,使用更多内存的进程将成为被杀死的受害者。

我在哪里可以找到OOMKiller的日志?

通常在/var/log目录下。/var/log/kern.log或/var/log/dmesg

希望这对你有所帮助。

一些典型的解决方案:

增加内存(不是交换) 找到程序中的内存泄漏并修复它们 限制任何进程可以使用的内存(例如,可以使用JAVA_OPTS限制JVM内存) 查看日志和谷歌:)

在lsf环境中(交互式或其他),如果应用程序的内存利用率超过了队列上的管理员预先设定的阈值,或者提交给队列的资源请求,那么进程将被杀死,这样其他用户就不会成为潜在运行的受害者。当它这样做时,它并不总是发送电子邮件,这取决于它的设置方式。

在这种情况下,一种解决方案是找到具有更大资源的队列,或者在提交中定义更大的资源需求。

你可能还想复习man ulimit

虽然我不记得导致了死亡,但我需要它已经有一段时间了。

用户可以使用kill或Control+C杀死自己的程序,但我的印象是这并没有发生,而且用户向您投诉了。

Root当然有杀死程序的能力,但如果有人在你的机器上安装了Root并杀死了一些东西,你就有更大的问题了。

如果您不是系统管理员,系统管理员可能对CPU、RAM、磁盘使用设置了配额,并且会自动杀死超过配额的进程。

除了这些猜测,没有更多关于这个项目的信息,我不能确定。

像systemtap(或跟踪程序)这样的工具可以监视内核信号传输逻辑和报告。例如,https://sourceware.org/systemtap/examples/process/sigmon.stp

# stap --example sigmon.stp -x 31994 SIGKILL
   SPID     SNAME            RPID  RNAME            SIGNUM SIGNAME
   5609     bash             31994 find             9      SIGKILL

该脚本中的过滤if块可以根据口味进行调整,也可以取消以跟踪系统范围的信号流量。可以通过收集回溯跟踪来进一步隔离原因(分别为内核和用户空间向探针添加print_backtrace()和/或print_ubacktrace())。

在我的例子中,这发生在一个Laravel队列工作者身上。系统日志没有提到任何杀死,所以我进一步查看,结果发现工作人员基本上是在杀死自己,因为一个作业超出了内存限制(默认设置为128M)。

使用——timeout=600和——memory=1024运行队列工作器为我解决了这个问题。