Linux OOM Killer 是什么?程序为什么突然被杀?

Linux OOM Killer 是什么?程序为什么突然被杀?

1. 前言

线上服务有时会突然消失。

你没有手动 kill,程序也没有正常退出,但进程就是没了。

查看日志后可能看到:

复制代码
Out of memory: Killed process 1234 (java)

这通常就是 Linux OOM Killer 触发了。

本文讲解:

  • OOM 是什么;
  • OOM Killer 为什么会杀进程;
  • 如何查看 OOM 日志;
  • Linux 怎么选择杀哪个进程;
  • 如何避免程序被 OOM;
  • Docker/Kubernetes 中 OOM 有什么特点。

2. OOM 是什么

OOM 全称:

复制代码
Out Of Memory

意思是内存不足。

当系统内存严重不足,无法满足新的内存分配请求时,Linux 内核可能会触发 OOM Killer。

OOM Killer 的作用是:

复制代码
选择一个或多个进程杀掉,释放内存,避免整个系统崩溃。

3. OOM Killer 为什么要杀进程

如果系统内存完全耗尽,可能导致:

  • 新进程无法启动;
  • 现有进程无法分配内存;
  • 系统响应变慢;
  • SSH 无法登录;
  • 内核关键路径受影响。

为了自保,内核会杀掉某个"代价较高"的进程,释放内存。

这就是 OOM Killer。


4. 如何查看 OOM 日志

使用 dmesg:

复制代码
dmesg | grep -i "out of memory"

查看被杀进程:

复制代码
dmesg | grep -i "killed process"

使用 journalctl:

复制代码
journalctl -k | grep -i "killed process"

或:

复制代码
journalctl -k | grep -i "oom"

示例:

复制代码
Out of memory: Killed process 1234 (java) total-vm:4096000kB, anon-rss:2048000kB

说明 PID 1234 的 java 进程被杀。


5. OOM 日志怎么看

示例字段:

复制代码
Killed process 1234 (java) total-vm:4096000kB, anon-rss:2048000kB, file-rss:0kB

含义:

字段 含义
PID 被杀进程 ID
进程名 例如 java、mysqld
total-vm 虚拟内存
anon-rss 匿名常驻内存
file-rss 文件映射内存
oom_score OOM 评分

重点看:

复制代码
哪个进程被杀
当时内存大概占用多少
是否频繁出现

6. Linux 怎么选择杀哪个进程

Linux 会给进程计算 OOM 分数。

查看某进程分数:

复制代码
cat /proc/PID/oom_score

查看调整值:

复制代码
cat /proc/PID/oom_score_adj

oom_score 越高,越容易被杀。

oom_score_adj 范围:

复制代码
-1000 到 1000
含义
-1000 尽量不被 OOM 杀
0 默认
1000 更容易被杀

不建议随便把业务进程设置为 -1000

如果所有进程都不让杀,系统可能更危险。


7. OOM 前的典型现象

常见表现:

  • free -h 中 available 很低;
  • Swap 使用很多;
  • vmstat 中 si/so 持续不为 0;
  • 应用内存持续上涨;
  • 系统响应变慢;
  • 日志中出现 OOM;
  • 进程无异常日志但突然退出。

查看:

复制代码
free -h
vmstat 1
ps aux --sort=-%mem | head

8. 常见导致 OOM 的原因

8.1 内存泄漏

进程 RSS 持续增长,最终被杀。

查看趋势:

复制代码
ps -p PID -o pid,%mem,rss,cmd

持续观察:

复制代码
pidstat -r -p PID 1
8.2 JVM 参数过大

例如服务器只有 2GB 内存,却设置:

复制代码
-Xmx3g

很容易 OOM。

8.3 MySQL/Redis 配置过大

Redis 如果没有设置 maxmemory,可能无限占用内存。

MySQL buffer pool、连接数配置过大,也会造成内存压力。

8.4 突发流量

大量请求导致:

  • 线程增多;
  • 队列堆积;
  • 缓存增长;
  • 对象创建增加。
8.5 容器内存限制

Docker 或 Kubernetes 设置了内存限制。

容器超过限制会被杀,即使宿主机还有内存。


9. Docker 中的 OOM

查看容器是否 OOM:

复制代码
docker inspect 容器名 | grep -i oom

或者:

复制代码
docker inspect --format='{{.State.OOMKilled}}' 容器名

如果输出:

复制代码
true

说明容器曾因 OOM 被杀。

运行容器时可以设置内存限制:

复制代码
docker run -d --memory=512m --name myapp myapp:1.0

如果应用超过 512MB,可能被 OOM kill。


10. 如何避免 OOM

10.1 监控内存

定期观察:

复制代码
free -h
ps aux --sort=-%mem | head

生产环境需要监控:

  • 内存使用率;
  • available;
  • Swap;
  • 进程 RSS;
  • OOM 日志。
10.2 合理配置应用内存

Java:

复制代码
-Xms512m -Xmx512m

Redis:

复制代码
maxmemory 1gb
maxmemory-policy allkeys-lru

MySQL:

复制代码
innodb_buffer_pool_size
max_connections
10.3 限制容器资源
复制代码
docker run --memory=1g --cpus=1 myapp

避免单个容器吃光宿主机资源。

10.4 增加 Swap

Swap 不是根本解决方案,但可以缓冲突发内存压力。

查看:

复制代码
swapon --show

11. OOM 排查流程

复制代码
dmesg | grep -i "killed process"
journalctl -k | grep -i oom
free -h
vmstat 1
ps aux --sort=-%mem | head
cat /proc/PID/oom_score

流程:

复制代码
确认是否 OOM
↓
找到被杀进程
↓
查看当时日志
↓
检查系统内存和 Swap
↓
分析进程内存趋势
↓
检查应用配置
↓
判断是否需要扩容或修复内存泄漏

12. 小结

OOM Killer 是 Linux 内核在内存严重不足时的自救机制。

关键点:

复制代码
OOM 不是普通应用异常退出
它是内核主动杀进程
dmesg/journalctl 可以查证据
oom_score 越高越容易被杀
容器也可能因内存限制被 OOM

常用命令:

复制代码
dmesg | grep -i "killed process"
journalctl -k | grep -i oom
free -h
vmstat 1
ps aux --sort=-%mem | head
docker inspect --format='{{.State.OOMKilled}}' 容器名

避免 OOM 的核心是:

复制代码
监控内存
限制单进程内存
合理配置 JVM/MySQL/Redis
设置容器资源限制
排查内存泄漏
必要时扩容

如果程序"突然没了",第一时间就应该查 OOM 日志。

相关推荐
百度智能云技术站3 小时前
当 CPU 成为 GPU 的隐性瓶颈:Btune 2.0 用自动化耗时分析打破性能黑盒
运维·自动化·gpu算力
电商API_180079052473 小时前
京东API对接|实现批量自动化获取京东商品价格更新商品库
大数据·运维·数据挖掘·自动化·网络爬虫
菜鸟是大神4 小时前
07-Claude Code 的常用命令和快捷键
linux·运维·服务器
hj2862514 小时前
Linux存储空间管理完整笔记
linux·运维·笔记
Szime4 小时前
AI服务器电源、充电桩、储能BMS项目,电子元器件BOM配单怎么做更高效?
运维·服务器·人工智能
weixin_408318044 小时前
企业级实时音视频方案怎么选?自建、SDK集成、全托管三套方案成本对比
运维·实时音视频
谪星·阿凯4 小时前
内网渗透之权限维持:从域环境到单机的持久化控制指南
运维·服务器·网络·网络安全
m0_737302584 小时前
OpenClaw的基础定义与发展历程
服务器
无风听海4 小时前
深入理解 ASP.NET Core Authentication Scheme 体系
运维·云计算·asp.net
Championship.23.244 小时前
Linux 3.0 中断机制深度解析:从传统PIC到现代中断架构的转折点
linux·运维·架构·中断