是什么杀死了我的程序,为什么?


614

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

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

被杀

在航站楼上。这发生了两次。我问其他终端是否有人使用kill命令杀死进程?没有。

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


23
linux杀死了我的进程,并在redhat上将其记录在/ var / log / messages中
Dean Hiller

1
另请参见unix.stackexchange.com上的此答案
理查德

此事件中有3个参与者:(1)(常见原因)占用过多内存并导致OOM状态的进程(2)发送SIGKILL(信号9)的内核将其终止并将事实记录在某个系统中类似于/var/log/messages(3)的日志,运行该进程的外壳,Killed当退出状态waitpid(2)指示子进程已从信号9
终止

在阅读@DeanHiller的答案后,我在Ubuntu/var/log/syslog
Dinei

Answers:


403

如果用户或sysadmin没有杀死内核可能拥有的程序。内核只会在极端的资源匮乏(例如内存+交换耗尽)等特殊情况下终止进程。


25
如果内核杀死了该进程,它将在某处的日志中放置一条消息吗?
sbq

186
我刚刚编写了一个在inifite循环中分配内存的程序。系统变慢后,在终端中显示“ Killed”,进程终止。文件/var/log/kern.log包含很多有关终止的信息。-感谢您的指点。
sbq

6
几乎可以肯定的是。TAING时,我看到了很多。许多学生会忘记释放对象,这些应用最终将达到3GB的虚拟内存使用量。它一到达那点就被杀死。
Herms,

8
当“程序只是崩溃”时,这实际上操作系统杀死进程!
2011年

79
使用dmesg看看内核日志:这里我找到内核杀死我的Python程序由于极端的虚拟内存消耗。
caneta

272

尝试:

dmesg -T| grep -E -i -B100 'killed process'

其中-B100表示杀死之前发生的行数。

在Mac OS上省略-T


6
仅供参考,从info egrep“egrep的是一样的grep -E ...直接调用或者作为egrep的或fgrep一样已经过时了。”

9
对于简单的模式,'killed process'您可以直接使用grep而不进行egrep其他更改。对于更复杂的模式,你会改变取代如egrep -i -B100 'foo|ba[rz]'grep -E -i -B100 'foo|ba[rz]'问答环节提供了更多细节。
航空

2
我也建议您使用dmesg -T以获得可读的时间戳
gukoff

171

这看起来像是一篇很好的文章:驯服OOM杀手

要点是Linux 过度使用记忆。当一个进程要求更多的空间时,即使没有其他进程要求它,Linux也会在没有人实际使用他们所要求的所有内存的情况下为其分配该空间。该进程将在实际使用时而不是在请求时独占使用已分配的内存。这样可以使分配更快,并且可能使您“作弊”并分配比实际更多的内存。但是,一旦进程开始使用此内存,Linux可能会意识到它在分配它没有的内存方面过于慷慨,因此必须终止进程以释放一些内存。要杀死的进程是基于考虑到运行时(长时间运行的进程更安全),内存使用(贪婪的进程不太安全)和其他一些因素的得分,包括您可以调整的值,以减少进程被终止的可能性。在本文中对此进行了更详细的描述。

编辑:这是另一篇文章,很好地解释了如何选择进程(带有一些内核代码示例的注释)。这样做的好处在于,它包含了对各种规则背后的推理的一些评论badness()


3
我真的很喜欢文章链接。我建议对本主题感兴趣的人阅读它们,尤其是对lwn文章的评论。
乔恩·布林赫斯特

4
“ Linux会给它那个空间,即使它被另一个进程要求也是如此。”这不是虚拟内存的工作原理……
Mooing Duck 2014年

1
这篇文章很老(2009年),并不是文章中建议的所有功能都在主线中。
Alex

50

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

假设您有512 RAM + 1GB交换内存。因此,从理论上讲,您的CPU可以访问总计1.5GB的虚拟内存。

现在,一段时间后,所有内存都可以在1.5GB内正常运行。但是您的系统突然(或逐渐)开始消耗越来越多的内存,并且达到了已用内存总量的95%左右。

现在说任何进程都要求内核提供大量的内存。内核检查可用内存,发现它无法为进程分配更多内存。因此它将尝试释放一些内存调用/调用OOMKiller(http://linux-mm.org/OOM)。

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

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

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

希望这会帮助你。

一些典型的解决方案:

  1. 增加内存(不交换)
  2. 在程序中查找内存泄漏并进行修复
  3. 限制任何进程可以消耗的内存(例如,可以使用JAVA_OPTS限制JVM内存)
  4. 查看日志和谷歌:)

17

这是Linux 内存不足管理器(OOM)。选择您的流程是出于“ 不良 ”的考虑-近期性,居民人数(正在使用的内存,而不只是分配的内存)和其他因素的组合。

sudo journalctl -xb

您会看到以下消息:

Jul 20 11:05:00 someapp kernel: Mem-Info:
Jul 20 11:05:00 someapp kernel: Node 0 DMA per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:    0, btch:   1 usd:   0
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 per-cpu:
Jul 20 11:05:00 someapp kernel: CPU    0: hi:  186, btch:  31 usd:  30
Jul 20 11:05:00 someapp kernel: active_anon:206043 inactive_anon:6347 isolated_anon:0
                                    active_file:722 inactive_file:4126 isolated_file:0
                                    unevictable:0 dirty:5 writeback:0 unstable:0
                                    free:12202 slab_reclaimable:3849 slab_unreclaimable:14574
                                    mapped:792 shmem:12802 pagetables:1651 bounce:0
                                    free_cma:0
Jul 20 11:05:00 someapp kernel: Node 0 DMA free:4576kB min:708kB low:884kB high:1060kB active_anon:10012kB inactive_anon:488kB active_file:4kB inactive_file:4kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 968 968 968
Jul 20 11:05:00 someapp kernel: Node 0 DMA32 free:44232kB min:44344kB low:55428kB high:66516kB active_anon:814160kB inactive_anon:24900kB active_file:2884kB inactive_file:16500kB unevictable:0kB isolated(anon):0kB isolated
Jul 20 11:05:00 someapp kernel: lowmem_reserve[]: 0 0 0 0
Jul 20 11:05:00 someapp kernel: Node 0 DMA: 17*4kB (UEM) 22*8kB (UEM) 15*16kB (UEM) 12*32kB (UEM) 8*64kB (E) 9*128kB (UEM) 2*256kB (UE) 3*512kB (UM) 0*1024kB 0*2048kB 0*4096kB = 4580kB
Jul 20 11:05:00 someapp kernel: Node 0 DMA32: 216*4kB (UE) 601*8kB (UE) 448*16kB (UE) 311*32kB (UEM) 135*64kB (UEM) 74*128kB (UEM) 5*256kB (EM) 0*512kB 0*1024kB 1*2048kB (R) 0*4096kB = 44232kB
Jul 20 11:05:00 someapp kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
Jul 20 11:05:00 someapp kernel: 17656 total pagecache pages
Jul 20 11:05:00 someapp kernel: 0 pages in swap cache
Jul 20 11:05:00 someapp kernel: Swap cache stats: add 0, delete 0, find 0/0
Jul 20 11:05:00 someapp kernel: Free swap  = 0kB
Jul 20 11:05:00 someapp kernel: Total swap = 0kB
Jul 20 11:05:00 someapp kernel: 262141 pages RAM
Jul 20 11:05:00 someapp kernel: 7645 pages reserved
Jul 20 11:05:00 someapp kernel: 264073 pages shared
Jul 20 11:05:00 someapp kernel: 240240 pages non-shared
Jul 20 11:05:00 someapp kernel: [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
Jul 20 11:05:00 someapp kernel: [  241]     0   241    13581     1610      26        0             0 systemd-journal
Jul 20 11:05:00 someapp kernel: [  246]     0   246    10494      133      22        0         -1000 systemd-udevd
Jul 20 11:05:00 someapp kernel: [  264]     0   264    29174      121      26        0         -1000 auditd
Jul 20 11:05:00 someapp kernel: [  342]     0   342    94449      466      67        0             0 NetworkManager
Jul 20 11:05:00 someapp kernel: [  346]     0   346   137495     3125      88        0             0 tuned
Jul 20 11:05:00 someapp kernel: [  348]     0   348    79595      726      60        0             0 rsyslogd
Jul 20 11:05:00 someapp kernel: [  353]    70   353     6986       72      19        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  362]    70   362     6986       58      18        0             0 avahi-daemon
Jul 20 11:05:00 someapp kernel: [  378]     0   378     1621       25       8        0             0 iprinit
Jul 20 11:05:00 someapp kernel: [  380]     0   380     1621       26       9        0             0 iprupdate
Jul 20 11:05:00 someapp kernel: [  384]    81   384     6676      142      18        0          -900 dbus-daemon
Jul 20 11:05:00 someapp kernel: [  385]     0   385     8671       83      21        0             0 systemd-logind
Jul 20 11:05:00 someapp kernel: [  386]     0   386    31573      153      15        0             0 crond
Jul 20 11:05:00 someapp kernel: [  391]   999   391   128531     2440      48        0             0 polkitd
Jul 20 11:05:00 someapp kernel: [  400]     0   400     9781       23       8        0             0 iprdump
Jul 20 11:05:00 someapp kernel: [  419]     0   419    27501       32      10        0             0 agetty
Jul 20 11:05:00 someapp kernel: [  855]     0   855    22883      258      43        0             0 master
Jul 20 11:05:00 someapp kernel: [  862]    89   862    22926      254      44        0             0 qmgr
Jul 20 11:05:00 someapp kernel: [23631]     0 23631    20698      211      43        0         -1000 sshd
Jul 20 11:05:00 someapp kernel: [12884]     0 12884    81885     3754      80        0             0 firewalld
Jul 20 11:05:00 someapp kernel: [18130]     0 18130    33359      291      65        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18132]  1000 18132    33791      748      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18133]  1000 18133    28867      122      13        0             0 bash
Jul 20 11:05:00 someapp kernel: [18428]    99 18428   208627    42909     151        0             0 node
Jul 20 11:05:00 someapp kernel: [18486]    89 18486    22909      250      46        0             0 pickup
Jul 20 11:05:00 someapp kernel: [18515]  1000 18515   352905   141851     470        0             0 npm
Jul 20 11:05:00 someapp kernel: [18520]     0 18520    33359      291      66        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18522]  1000 18522    33359      294      64        0             0 sshd
Jul 20 11:05:00 someapp kernel: [18523]  1000 18523    28866      115      12        0             0 bash
Jul 20 11:05:00 someapp kernel: Out of memory: Kill process 18515 (npm) score 559 or sacrifice child
Jul 20 11:05:00 someapp kernel: Killed process 18515 (npm) total-vm:1411620kB, anon-rss:567404kB, file-rss:0kB

12

正如dwc和Adam Jaskiewicz所说,罪魁祸首很可能是OOM杀手。但是,接下来的下一个问题是:如何防止这种情况发生?

有几种方法:

  1. 如果可以,给系统更多的RAM(如果是VM,则很容易)
  2. 确保OOM杀手选择其他过程。
  3. 禁用OOM Killer
  4. 选择一个禁用OOM Killer的Linux发行版。

多亏了本文,我发现(2)特别容易实现。


2
那是我的记忆。我从2GB升级到4GB RAM,问题消失了。现在问题出在法案上:P
格斯

9

限制资源PAM模块完全导致了您描述的结果:我的进程神秘地了,控制台窗口上显示了Killed字样syslogkern.log中都没有日志输出。该顶部程序帮助我发现CPU的使用率正好一分钟后我的进程就会被杀死。


8

诸如systemtap(或跟踪器)之类的工具可以监视内核信号传输逻辑并进行报告。例如,https://sourceware.org/systemtap/examples/process/sigmon.stp

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

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


4

在lsf环境中(交互或其他方式),如果应用程序超出了队列管理员的队列利用率或提交队列中的资源请求的内存利用率,超出了某些预设阈值,则进程将被杀死,因此其他用户不会成为潜在用户的受害者逃跑。它发送电子邮件的时间并不总是取决于发送电子邮件的方式。

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

您可能还需要查看 man ulimit

虽然我不记得了ulimit,导致Killed其一直一段时间我需要这一点。


2

在Linux的客户站点(我认为是Red Hat)下,我们经常遇到问题,OOMKiller(内存不足的杀手)杀死了我们的主要应用程序(即服务器存在的原因)及其数据库进程。

在每种情况下,OOMKiller都只是简单地认为进程正在占用大量资源...机器甚至不会因为缺乏资源而发生故障。应用程序或其数据库都没有内存泄漏(或任何其他资源泄漏)的问题。

我不是Linux专家,但是我宁愿收集它的算法来决定何时杀死某些事物以及杀死什么是复杂的。另外,我被告知(我不能说出它的准确性)OOMKiller已嵌入内核,您不能简单地不运行它。


1
IIRC和OOMKiller仅在不得已时才被调用。我认为系统甚至会向各种应用程序发送信号,要求它们在被迫调用OOMKiller之前先放弃一些资源。带着一粒盐,因为已经很久了……
rmeador

1
可以根本不运行它。它被烘焙到内核中,但是有一些选项可以调整它的运行方式,甚至可以杀死它的进程。它在整个系统内存不足时运行,而不是在特定进程使用过多内存时运行。请参阅我的答案以获取更多详细信息。
亚当·贾斯基维奇

6
不运行oomkiller是很容易的。echo "2" > /proc/sys/vm/overcommit_memory
R .. GitHub STOP HELPING ICE 2012年

红帽不希望允许它改变:sudo echo "2" > /proc/sys/vm/overcommit_memory的/ proc / sys目录/ VM / overcommit_memory:权限被拒绝
布伦特浮士德

2
试试echo 2 | sudo tee /proc/sys/vm/overcommit_memory
Hypershadsy 2015年

2

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

运行队列工作器--timeout=600--memory=1024为我解决了问题。


0

用户可以使用kill或Control + C杀死自己的程序,但是我得到的印象不是发生什么,而是用户向您抱怨。

root当然具有杀死程序的能力,但是如果有人在您的计算机上拥有root并杀死某些东西,那么您将遇到更大的问题。

如果您不是sysadmin,则sysadmin可能已在CPU,RAM,磁盘磁盘使用量和超过这些限制的自动杀死进程上设置了配额。

除了这些猜测之外,我不确定是否没有有关该程序的更多信息。


6
CTRL-C发送的kill与报告的OP不同(我记得SIGINT(2),而程序正在接收SIGKILL(9))。
Powerlord

0

我最近遇到了这个问题。最终,我发现在自动调用Opensuse zypper更新后,我的进程被杀死了。禁用zypper更新解决了我的问题。


我看到了同样的问题。您如何跟踪哪个进程杀死了您的进程?似乎有一种工具可以检查谁将SIGKILL发送给进程。
Howy 2014年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.