我的应用程序在Linux上作为后台进程运行。它目前是在终端窗口中的命令行中启动。
最近,一个用户正在执行该应用程序,并且它神秘地死亡。终端上显示出如下文本:
已杀死
这种情况发生了两次。我问过一个不同的终端是否使用kill命令来终止该进程?没有。
在什么条件下,Linux会决定杀死我的进程?我相信shell显示"已杀死",因为进程在收到kill(9)信号后死亡。如果Linux发送kill信号,那么系统日志中应该有一条消息,解释为什么要杀死它吗?
如果用户或系统管理员没有杀死程序,则可能是内核干的。内核只会在极端情况下,例如资源极度匮乏(如内存和交换空间耗尽)时才会终止进程。
dmesg
命令查看内核日志:我发现我的 Python 进程由于极端虚拟内存消耗而被内核杀死。 - caneta尝试:
dmesg -T| grep -E -i -B100 'killed process'
-B100
表示杀掉进程前的行数。
在 Mac OS 上不需要加 -T。
info egrep
中可以得知:"egrep与grep -E相同。...直接使用egrep或fgrep已经过时了。" - Airgrep
而不进行其他更改。对于更复杂的模式,您需要将例如egrep -i -B100 'foo|ba[rz]'
替换为grep -E -i -B100 'foo|ba[rz]'
。这个问题和答案提供了更多细节。 - Airdmesg -T
命令,以获得可读的时间戳。 - gukoffdmesg -T| grep -E 'Killed process'
。 - Meet Sinojiadmesg
命令只显示存储在内核环形缓冲区中的消息。如果您正在搜索OOM(内存不足)消息,它们有可能被覆盖,无法通过dmesg命令访问。您需要在其他位置进行搜索,如/var/log/kern.log
或/var/log/messages
。 - caltuntasbadness()
规则背后的推理的评论。假设你有 512MB 的内存和 1GB 的交换空间,因此理论上,你的 CPU 可以访问总共 1.5GB 的虚拟内存。
现在,在 1.5GB 的总内存范围内,一段时间内一切都正常运行。但是突然(或逐渐)你的系统开始消耗更多的内存,并且它已经达到了总内存使用量约为 95% 的一个点。
现在,假设任何进程已从内核请求大块内存。内核检查可用内存并发现无法为进程分配更多内存。因此,它将尝试通过调用/触发 OOMKiller (http://linux-mm.org/OOM) 来释放一些内存。
OOMKiller 有自己的算法来为每个进程评分。通常使用更多内存的进程成为要被杀死的受害者。
通常在 /var/log 目录中。可以是 /var/log/kern.log 或 /var/log/dmesg
希望这可以帮助你。
这是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
正如dwc和Adam Jaskiewicz所说,罪魁祸首很可能是OOM Killer。不过,接下来的问题是:我该如何预防这种情况呢?
有几种方法:
我发现第二种方法特别容易实现:
将 /proc/<PID>/oom_score_adj
调整为 -1000
(这会自动将 oom_adj
设为 -17
,将 oom_score
设为 0
)。
请参见如何在Linux中创建OOM排除项了解更多信息。
/proc/<PID>/oom_score_adj
调整为 -1000(这会自动将 oom_adj
调整为 -17,将 oom_score
调整为 0,因此你的进程永远不会被杀掉)。 - maganap像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()
用于内核和用户空间,分别)。
限制资源的PAM模块正是导致了你所描述的情况: 我的进程突然死亡并在控制台窗口上显示“Killed”字样,没有任何日志输出,无论是在syslog还是在kern.log中都没有。使用top程序帮助我发现,我的进程在使用CPU一分钟后就会被终止。
在我的情况下,这是在Laravel队列工作者中发生的。系统日志没有提到任何杀死进程的信息,所以我进一步查看后发现,工作者基本上是因为一个作业超过了内存限制(默认设置为128M)而自行终止。
使用 --timeout=600
和 --memory=1024
运行队列工作者可以解决我的问题。
/var/log/messages
)中记录此事实;(3) 该进程所在的shell,当从waitpid(2)
函数的退出状态指示子进程死亡信号为9时,打印出“Killed”通知的进程。 - arielf/var/log/syslog
目录下。 - Dinei