OOM Killer 主动杀进程保系统,非随机:需通过 dmesg 日志定位时间、进程及 Mem-Info 快照;用 /proc/meminfo、slabtop、smem 分层验证真实内存压力;结合 VmRSS/VmSize、缺页统计和 GC 日志定位泄漏;临时缓解可用 drop_caches,长期应调优 overcommit 和 oom_score_adj。

Linux 内核内存耗尽触发的随机终止,本质是 OOM Killer 主动杀进程保系统,不是“随机”,而是有迹可循——关键在日志、内存分层使用和进程真实开销。
看懂 dmesg 里的 OOM 日志
这是第一手证据,不能只扫一眼“Killed process”。要重点抓三块:
- 时间戳:对照业务日志,确认是否发生在定时任务、批量导入或流量高峰时
- “Killed process XXX (pid YYY)”行:记下进程名和 PID,注意它不一定是 RSS 最高的那个,而是 oom_score_adj 综合得分最高的
- 紧随其后的 “Mem-Info” 快照:重点关注 Active(anon) 和 Inactive(anon) —— 如果这两项远高于 Cached,说明是匿名页(堆/栈)吃光内存;如果 SwapCached 或 PageTables 异常高,可能是页表膨胀或 swap 使用失控
别信 free -h 的 available,查真实内存压力
available 是估算值,OOM 常发生在 available 还剩几百 MB 时。必须分层验证:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
- 运行 cat /proc/meminfo | grep -E "(Committed_AS|CommitLimit|MemAvailable|SReclaimable)":若 Committed_AS 接近或超过 CommitLimit,说明虚拟内存已超限,OOM 必然发生
- 运行 slabtop -o:观察 dentry、inode、ext4_inode_cache 等 slab 对象是否持续增长,内核缓存泄漏会悄无声息吃掉数 GB 内存
- 运行 smem -w -k -c "pid user command pss uss" | head -15:PSS 比 RSS 更准,能反映进程实际占用的物理内存份额,尤其适合识别 Java 或 Python 中多个实例共享内存的场景
定位进程内存增长源头
找到高 PSS 进程后,不能只 kill,要判断它是真占内存,还是虚占:
- 对比虚拟内存与实际驻留:执行 cat /proc/PID/status | grep -E "VmRSS|VmSize",再算 cat /proc/PID/smaps | awk '/^Size:/ {sum+=$2} END {print sum}',若 VmSize 远大于 VmRSS,说明大量 mmap 区域未真正使用(如 JVM 堆外内存预分配、大文件映射)
- 观察缺页行为:用 perf record -e page-faults,major-faults -p PID 跑 30 秒,major-fault 高意味着频繁从磁盘或 swap 加载页,可能正在撑爆内存
- 对 Java 应用:检查是否加了 -XX:+PrintGCDetails -Xloggc:gc.log,GC 日志里若 Full GC 频繁且回收效果差,或 DirectByteBuffer 分配量持续上涨,就是典型泄漏信号
临时缓解与长期规避
OOM 是结果,不是原因。临时止血后,必须切断根源:
- 紧急时可临时释放部分缓存:sync; echo 3 > /proc/sys/vm/drop_caches(仅限 buff/cache 占比极高且非生产核心时段)
- 防止误杀关键服务:给重要进程设低 oom_score_adj,如 echo -100 > /proc/PID/oom_score_adj
- 长期治理看 vm.overcommit_memory:设为 2 可严格限制内存分配(配合 overcommit_ratio),避免 malloc 成功但后续实际分配时崩溃;设为 0 是默认,较宽松但易触发 OOM

















