', 'auto'); ga('send', 'pageview'); 明明白白的赛特 – 如何事后找出被因使用过多内存被杀死的进程(OOM)

如何事后找出被因使用过多内存被杀死的进程(OOM)

在 2024-02-27 发布于 linux系统 分类

通常linux系统中会有一个专门的程序监控左右程序的运行,当有进程内存占用过大的时候,监控程序会杀死这个进程。 这样可以防止整个系统的内存被用完导致崩溃的情况。这个监控程序一般被成为Out-Of-Memory Killer。 程序因占用内存过多被杀死的情况一般被称为(OOM)。

当系统的大部分内存被一个程序占用的时候,系统会出现响应缓慢的情况。 此时我们往往会收到各种告警,但是因为系统响应缓慢,一般无法远程登陆查看情况。 因此事后找出哪个进程被OOM Killer杀死对于防止后续类似情况出现就非常重要。

简单来说,可以通过下面的命令从systemd日志中找出来那个进程被OOM Killer杀死:

journalctl --list-boots | \
    awk '{ print $1 }' | \
    xargs -I{} journalctl --utc --no-pager -b {} -kqg 'killed process' -o verbose --output-fields=MESSAGE

下面是对这个命令的拆解:

  1. journalctl 是一个用于查询 systemd 日志的工具。

  2. --list-boots: 列出系统的所有启动记录。完整的输出是这个样子的:

``` $ journalctl --list­-boots

-136 6e7ae03aa0a4887a6 Mon 2020-10-12 00:59:31 +03—Mon 2020-10-12 01:02:06 +03 -135 5e8f616769a4413b1 Mon 2020-10-12 01:02:38 +03—Mon 2020-10-12 02:55:47 +03 -134 7b839631c654dba8e Mon 2020-10-12 02:56:29 +03—Wed 2020-10-14 00:16:38 +03 .. -3 539bf36b695fd69b3 Wed 2021-01-27 10:25:02 +03—Wed 2021-01-27 20:46:49 +03 -2 d16424126db2a34b6 Wed 2021-01-27 20:47:43 +03—Wed 2021-01-27 23:53:16 +03 -1 d4ca25900037bb9a1 Thu 2021-01-28 10:15:03 +03—Fri 2021-01-29 20:48:03 +03 0 041a418db54e4fabc6 Fri 2021-01-29 20:48:41 +03—Sat 2021-01-30 20:57:10 +03 ```

  1. awk '{ print $1 }': 打印出前面那个命令输出的每行的第一个字段,即启动记录编号

  2. xargs -I{}: 用前一步过滤出来的启动记录编号,逐个构建后续的journalctl命令并运行。

  3. journalctl --utc --no-pager -b {} -kqg 'killed process' -o verbose --output-fields=MESSAGE`

    • 这一段都是传递给 xargs 的命令。
    • --utc:将消息中的时间转换为UTC。当处理来自其它系统的日志的时候,这个参数能确保我们得到含义一致的时间。
    • --no-pager:不将输出传递给分页程序,直接输出到终端。
    • -b {}:使用 {}(由 xargs 替换为启动序列标识符)指定要查询的启动序列。
    • -kqg 'killed process' 这其实是三个命令选项的合并:
      • -k 使用_TRANSPORT=kernel过滤消息,也就是过滤出内核事件
      • -q 过滤掉提示性的消息
      • -g 'killed progress' 以正则表达式过滤
    • -o verbose:以详细格式输出。
    • --output-fields=MESSAGE:仅输出与消息相关的字段。