ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

被杀

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

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

linux杀死了我的进程并将其登录到redhat上的/var/log/messages
另请参阅 unix.stackexchange.com 上的 this answer
此事件有 3 个参与者:(1)(常见原因)占用过多内存并导致 OOM 条件的进程(2)发送 SIGKILL(信号 9)以终止它并在某些系统中记录事实的内核log like /var/log/messages (3) 进程运行的 shell,当 waitpid(2) 的退出状态表明子进程死于信号 9 时,打印 Killed 通知的进程。
阅读@DeanHiller 的回答后,我在 Ubuntu 上的 /var/log/syslog 下找到了日志消息

d
dwc

如果用户或系统管理员没有杀死内核可能拥有的程序。内核只会在资源极度匮乏(想想 mem+swap 耗尽)等特殊情况下杀死进程。


如果内核杀死了该进程,它会在某处的日志中放置一条消息吗?
我刚刚写了一个在无限循环中 malloc 内存的程序。系统变慢后,终端显示“Killed”并终止进程。文件 /var/log/kern.log 包含很多关于终止的信息。 - 感谢您的指点。
几乎肯定是这样。我在TAing时看到了很多。许多学生会忘记释放他们的对象,这些应用程序最终会达到 3GB 的虚拟内存使用量。当它到达那个点时,它就被杀死了。
当“程序简单地崩溃”时,那是操作系统实际上杀死了进程!
使用 dmesg 查看内核日志:在这里我发现我的 python 进程由于极端的虚拟内存消耗而被内核杀死。
R
Ravindranath Akila

尝试:

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

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

在 Mac OS 上省略 -T。


仅供参考,来自 info egrep:“egrep 与 grep -E 相同。...直接调用 egrep 或 fgrep 已被弃用”
对于像 'killed process' 这样的简单模式,您可以只使用 grep 而不是 egrep 而无需进行其他更改。对于更复杂的模式,您可以将替换例如 egrep -i -B100 'foo|ba[rz]' 更改为 grep -E -i -B100 'foo|ba[rz]'This Q&A 提供了更多详细信息。
我还建议使用 dmesg -T 以获得可读的时间戳
如果您只想查看服务器上最近终止的进程列表,请尝试使用 dmesg -T| grep -E 'Killed process'
D
Drazisil

这看起来是一篇关于该主题的好文章:Taming the OOM killer (1)。

要点是 Linux 过度使用内存。当一个进程请求更多空间时,Linux 会给它这个空间,即使它被另一个进程占用,假设没有人真正使用他们请求的所有内存。该进程将在实际使用它时获得它分配的内存的独占使用权,而不是在它请求时。这使得分配速度更快,并且可能允许您“作弊”并分配比实际更多的内存。然而,一旦进程开始使用这个内存,Linux 可能会意识到它在分配它没有的内存方面过于慷慨,并且必须终止一个进程以释放一些内存。要杀死的进程基于考虑运行时(长时间运行的进程更安全)、内存使用量(贪婪进程不太安全)和其他一些因素的分数,包括您可以调整的值以减少进程很可能会被杀死。这一切都在文章中进行了更详细的描述。

编辑:这里是 [another article] (2),它很好地解释了如何选择进程(用一些内核代码示例进行注释)。这样做的好处在于,它包含了对各种 badness() 规则背后的推理的一些评论。


我真的很喜欢文章链接。我建议任何对该主题感兴趣的人阅读它们——尤其是对 lwn 文章的评论。
“即使它被另一个进程占用,Linux也会给它那个空间”这不是虚拟内存的工作原理......
这篇文章很旧(2009 年),并不是文章中建议的所有功能都在主线中。
J
Jadav Bheda

让我先解释一下何时以及为什么会调用 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

希望这会帮助你。

一些典型的解决方案:

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


m
mikemaccana

这是 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

如何找出内存不足量?
@TD1 它取决于数据量——通常你会有一个进程的堆快照(这取决于所使用的编程语言/VM)。但答案可能是——“赤字是无限的,因为你有内存泄漏”——例如,你正在添加一个你正在使用的数组,而且你的程序运行的时间越长,它就会变得越大。
C
Carl

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

有几种方法:

如果可以的话,给你的系统更多的内存(如果它是一个虚拟机就很容易)确保 OOM 杀手选择不同的进程。禁用 OOM Killer 选择禁用 OOM Killer 的 Linux 发行版。

多亏了 this article,我发现 (2) 尤其容易实现。


这对我来说是 RAM。我从 2GB RAM 升级到 4GB RAM,问题消失了。现在问题出在账单上:P
方式#2:这篇文章很有用,但已经过时了。您现在应该将 /proc/<PID>/oom_score_adj 调整为 -1000(它会自动将 oom_adj 调整为 -17 并将 oom_score 调整为 0,因此您的进程永远不会被终止)
f
fche

像 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() 到探测器)。


C
Christian Ammer

PAM module to limit resources 导致了您所描述的结果:我的进程神秘地死亡,控制台窗口上显示文本 Killedsyslogkern.log 中都没有日志输出。 top 程序帮助我发现,在 CPU 使用一分钟后,我的进程就被终止了。


k
kenorb

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

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

您可能还想查看 man ulimit

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


i
iSWORD

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

使用 --timeout=600--memory=1024 运行队列工作程序为我解决了这个问题。


L
Lawrence Dol

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

在每种情况下,OOMKiller 都只是简单地确定进程正在使用大量资源……机器甚至不会因为缺乏资源而失败。应用程序和它的数据库都没有内存泄漏(或任何其他资源泄漏)的问题。

我不是 Linux 专家,但我宁愿收集它的算法来决定何时杀死某些东西以及杀死什么是复杂的。另外,有人告诉我(我不能说这句话的准确性)OOMKiller 被嵌入到内核中,你不能简单地不运行它。


IIRC,OOMKiller 仅作为最后的手段被调用。我认为系统甚至会向各种应用程序发送信号,要求它们在被迫调用 OOMKiller 之前放弃一些资源。带上一粒盐,因为它已经很长时间了......
你可以根本不运行它。它被嵌入内核,但有一些选项可以调整它的运行方式,甚至它可能会杀死哪些进程。它在整个系统内存不足时运行,而不是在特定进程使用过多时运行。有关更多详细信息,请参阅我的答案。
不运行oomkiller 很容易。 echo "2" > /proc/sys/vm/overcommit_memory
Red Hat 不想让它被改变:sudo echo "2" > /proc/sys/vm/overcommit_memory /proc/sys/vm/overcommit_memory: Permission denied
试试echo 2 | sudo tee /proc/sys/vm/overcommit_memory
T
Tom Ritter

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

root 当然有能力杀死程序,但如果有人在你的机器上有 root 并且正在杀死东西,你就有更大的问题。

如果您不是系统管理员,系统管理员可能已经设置了 CPU、RAM 或磁盘使用配额,并自动终止超过这些配额的进程。

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


CTRL-C 发送的终止与 OP 报告的不同(我记得是 SIGINT (2),而程序正在接收 SIGKILL (9))。
p
poordeveloper

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


我看到了同样的问题。你如何追踪哪个进程杀死了你的进程?似乎有一个工具可以检查谁向进程发送 SIGKILL。