OOM Killer 概述
当系统物理内存耗尽且无法回收足够内存时,Linux 内核会调用 OOM Killer(Out-Of-Memory Killer)机制,选择一个进程将其终止以释放内存,避免系统崩溃。
OOM Killer 的触发流程:

关键概念:
调用 OOM Killer 的进程 ≠ 被杀的进程。调用者只是"恰好触发内存分配失败的那个进程",被杀的是
oom_score 最高的进程。OOM Killer 是内核的兜底保护机制,触发说明系统内存已经严重不足。
如何确认发生了 OOM
查看内核环形缓冲区(ring buffer)中的日志消息,是排查 OOM 事件的首选方法。
方法一:使用 dmesg 查看内核日志
dmesg -T | grep -i "oom-killer\\|out of memory\\|Killed process"
方法二:使用 journalctl 查看内核日志
说明:
journalctl 是 systemd 提供的日志查询工具,可按时间范围筛选内核日志,适用于配置了 systemd 的系统:journalctl -k --since "1 hour ago" | grep -i "oom\\|killed process"
方法三:查看系统日志文件
对于未使用 systemd 的系统,可直接检索
/var/log/messages 中的内核日志记录:grep -i "oom\\|killed process" /var/log/messages
以上方式,如果输出中包含
invoked oom-killer 或 Killed process,则说明发生了 OOM 事件。方法四:查看系统内存状态(辅助)
除了排查日志,还可通过以下命令查看当前系统的内存使用情况,辅助判断是否存在内存压力:
# 查看系统整体内存使用概况(总量/已用/可用/缓存)free -h# 查看详细内存信息(对应 OOM 日志中的 Mem-Info 字段)cat /proc/meminfo# 实时监控内存变化(每秒刷新,共 5 次)vmstat 1 5# 查看 RSS(物理内存占用)最高的进程ps aux --sort=-%mem | head -20
OOM 日志逐段解读
以下基于一条真实的 TencentOS Server OOM 日志,逐段解读各字段含义。
第一段:触发信息
Aug 2 00:55:46 VM-223-103-tlinux kernel: bkmonitorbeat invoked oom-killer: gfp_mask=0x14201ca(GFP_HIGHUSER_MOVABLE|__GFP_COLD), nodemask=(null), order=0, oom_score_adj=0
本例值 | 字段 | 含义 |
bkmonitorbeat | 进程名 | 触发 OOM Killer 的进程名称(调用者,非被杀进程) |
0x14201ca | gfp_mask | 内存分配标志,括号内为可读形式。 GFP_HIGHUSER_MOVABLE 表示申请高端用户态可移动页 |
(null) | nodemask | NUMA 节点掩码,限制从哪些节点分配内存。 null 表示不限制 |
0 | order | 申请的页面阶数。0 = 1 个页面(4KB),1 = 2 个页面(8KB),以此类推 |
0 | oom_score_adj | OOM 评分调整值,范围 -1000~1000。正值增加被杀概率,负值降低 |
注意:
nodemask 是 NUMA 概念,cpuset.mems_allowed 是 cpuset 概念,两者功能类似但来源不同。即使 nodemask=null,进程仍可能被 cpuset 限制在特定 NUMA 节点上。第二段:进程上下文
Aug 2 00:55:46 VM-223-103-tlinux kernel: bkmonitorbeat cpuset=collector-bkmonitorbeat-62c1e40fc0a151a2d1796808a16b083c mems_allowed=0Aug 2 00:55:46 VM-223-103-tlinux kernel: CPU: 15 PID: 14566 Comm: bkmonitorbeat Not tainted 4.14.105-1-tlinux3-0023 #1Aug 2 00:55:46 VM-223-103-tlinux kernel: Hardware name: Tencent Cloud CVM, BIOS seabios-1.9.1-qemu-project.org 04/01/2014
各项参数说明如下:
本例值 | 字段 | 含义 |
collector-bkmonitorbeat-... | cpuset | 进程所在的 cgroup cpuset 路径 |
0 | mems_allowed | 允许使用的 NUMA 节点。 0 表示只能在 node 0 分配内存 |
15 | CPU | 触发时所在的 CPU 核心 |
14566 | PID | 进程 ID |
4.14.105-1-tlinux3-0023 | 内核版本 | 当前运行的内核版本 |
Tencent Cloud CVM | Hardware | 硬件信息 |
说明:
TencentOS Server 3 的 OOM 日志格式在不同内核版本间基本一致,而 TencentOS Server 4 字段会更多(如
writepending、shmem_thp 等),但解读方法相同。第三段:内核调用栈与寄存器
Aug 2 00:55:46 VM-223-103-tlinux kernel: Call Trace:Aug 2 00:55:46 VM-223-103-tlinux kernel: dump_stack+0x63/0x8aAug 2 00:55:46 VM-223-103-tlinux kernel: dump_header+0x9f/0x204Aug 2 00:55:46 VM-223-103-tlinux kernel: oom_kill_process+0x22c/0x440Aug 2 00:55:46 VM-223-103-tlinux kernel: out_of_memory+0x114/0x4a0Aug 2 00:55:46 VM-223-103-tlinux kernel: __alloc_pages_slowpath+0x837/0xab5Aug 2 00:55:46 VM-223-103-tlinux kernel: __alloc_pages_nodemask+0x236/0x2a0Aug 2 00:55:46 VM-223-103-tlinux kernel: alloc_pages_current+0x6a/0xb0...
调用栈展示了 OOM Killer 的触发路径:

第四段:Mem-Info 内存概况
查看 mem-info 指令:
# 查看系统内存详情(对应 Mem-Info 中的各字段)cat /proc/meminfo# 查看 Slab 缓存使用情况cat /proc/slabinfo | head -5# 查看各 NUMA 节点内存分布cat /sys/devices/system/node/node*/meminfo | grep -i "active\\|free\\|slab"
输出示例:
Aug 2 00:55:46 VM-223-103-tlinux kernel: Mem-Info:active_anon:16087067inactive_anon:27297active_file:1083inactive_file:913unevictable:0dirty:1writeback:0slab_reclaimable:49598slab_unreclaimable:29114mapped:3640shmem:68701pagetables:46710free:73341free_pcp:2500free_cma:0
说明:数值以 page 为单位,x86 架构下 1 page = 4 KB。可用
getconf PAGE_SIZE 查看页面大小。各项参数说明如下:
字段 | 本例值(页) | 换算 | 含义 |
active_anon | 16,087,067 | ~61.3 GB | 活跃匿名内存(进程堆/栈等),OOM 分析重点关注项 |
inactive_anon | 27,297 | ~107 MB | 非活跃匿名内存 |
active_file | 1,083 | ~4.2 MB | 活跃文件缓存(文件页) |
inactive_file | 913 | ~3.6 MB | 非活跃文件缓存,可回收 |
slab_reclaimable | 49,598 | ~194 MB | 可回收的 Slab 缓存(dentry/inode 等) |
slab_unreclaimable | 29,114 | ~114 MB | 不可回收的 Slab 缓存 |
shmem | 68,701 | ~268 MB | 共享内存(tmpfs/shmem) |
pagetables | 46,710 | ~183 MB | 页表占用 |
free | 73,341 | ~286 MB | 空闲页 |
本例分析:
active_anon 占 61.3 GB ,占比最高,说明匿名内存(进程堆)消耗了绝大部分内存,远超系统可回收能力,直接导致 OOM。第五段:各 NUMA 节点与 zone 详情
Aug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 Normal: free:32000kB min:30980kB low:93628kB high:156276kB ...
重点关注
free 与 low 的关系:zone | free | low | 判断 |
DMA | 15,876 kB | 16 kB | 正常 |
DMA32 | 246,028 kB | 4,096 kB | 正常 |
Normal | 32,000 kB | 93,628 kB | free 低于 low,触发 OOM 的直接原因 |
当 zone 的
free 低于 low 水位线时,内核认为该 zone 内存严重不足,触发 OOM Killer。第六段:buddyinfo 内存碎片化情况
Aug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 Normal: 1480*4kB (UME) 678*8kB (UME) 574*16kB (UME) 193*32kB (UME) 86*64kB (UM) 10*128kB (UM) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 33488kB
buddyinfo 展示各阶空闲页面的分布。本示例 Normal zone 虽然 free 总量有 33 MB,但全是 4KB~128KB 的小块,没有 256KB 以上的连续大页,说明内存碎片化严重。虽然碎片化本身不是 OOM 的直接原因(order=0 只需 4KB),但碎片化会加剧高阶分配的失败率。
第七段:大页信息
Aug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB
本示例未配置大页,
hugepages_total=0。常见 OOM 原因与排查方向
原因 | 特征 | 排查命令 |
进程内存泄漏 | active_anon 持续增长不回落 | top/ps aux --sort=-rss 找 RSS 最高的进程 |
cgroup 内存限制 | 日志含 memory.max 或 cgroup 路径 | cat /sys/fs/cgroup/<path>/memory.max |
Slab 缓存膨胀 | slab_unreclaimable 异常大 | cat /proc/slabinfo 或 slabtop |
共享内存过量 | shmem 数值大 | ipcs -m 查看共享内存段 |
内存碎片化 | buddyinfo 高阶页面为 0 | cat /proc/buddyinfo |
预防与调优
调整进程 OOM 优先级
保护关键进程不被 OOM Killer 杀死:
# 降低被杀概率(-1000 等于完全禁止 OOM 杀死该进程)echo -1000 > /proc/<pid>/oom_score_adj# 永久设置(写入 systemd service) 在 [Service] 段添加:OOMScoreAdjust=-100
使用 cgroup 限制内存
防止单个进程消耗过多内存:
# cgroup v2 示例:限制进程最大内存为 4GBmkdir /sys/fs/cgroup/myappecho 4G > /sys/fs/cgroup/myapp/memory.maxecho <pid> > /sys/fs/cgroup/myapp/cgroup.procs
配置 swap
适当配置 swap 可以在物理内存不足时提供缓冲(不推荐对性能敏感场景使用大 swap):
# 查看 swap 状态swapon --showfree -h
升级实例规格
当业务负载确实超出当前实例的内存容量,且无法通过应用层优化(如修复内存泄漏、调整缓存策略)解决时,可考虑升级实例规格以增加可用内存:
# 查看当前实例内存规格free -h# 查看内核识别的物理内存总量grep MemTotal /proc/meminfo
在腾讯云控制台或通过 API 调整实例规格时,建议注意以下事项:
升级实例规格通常需要重启实例,请提前做好业务切换和应急预案。
部分实例类型支持在线变配(无需停机),具体支持的类型以云服务器产品文档为准。
升级前建议先排查是否存在内存泄漏或配置不当,避免仅通过扩容掩盖问题。
监控告警
建议对以下指标设置告警:
可用内存低于总内存 10%
oom-killer 事件出现次数 > 0进程 RSS 接近系统内存总量
# 快速检查是否曾有 OOM 事件dmesg -T | grep -c "oom-killer"
附录:完整 OOM 日志样本
以下为本文档分析使用的完整日志,供参考:
Aug 2 00:55:46 VM-223-103-tlinux kernel: bkmonitorbeat invoked oom-killer: gfp_mask=0x14201ca(GFP_HIGHUSER_MOVABLE|__GFP_COLD), nodemask=(null), order=0, oom_score_adj=0Aug 2 00:55:46 VM-223-103-tlinux kernel: bkmonitorbeat cpuset=collector-bkmonitorbeat-62c1e40fc0a151a2d1796808a16b083c mems_allowed=0Aug 2 00:55:46 VM-223-103-tlinux kernel: CPU: 15 PID: 14566 Comm: bkmonitorbeat Not tainted 4.14.105-1-tlinux3-0023 #1Aug 2 00:55:46 VM-223-103-tlinux kernel: Hardware name: Tencent Cloud CVM, BIOS seabios-1.9.1-qemu-project.org 04/01/2014Aug 2 00:55:46 VM-223-103-tlinux kernel: Call Trace:Aug 2 00:55:46 VM-223-103-tlinux kernel: dump_stack+0x63/0x8aAug 2 00:55:46 VM-223-103-tlinux kernel: dump_header+0x9f/0x204Aug 2 00:55:46 VM-223-103-tlinux kernel: oom_kill_process+0x22c/0x440Aug 2 00:55:46 VM-223-103-tlinux kernel: out_of_memory+0x114/0x4a0Aug 2 00:55:46 VM-223-103-tlinux kernel: __alloc_pages_slowpath+0x837/0xab5Aug 2 00:55:46 VM-223-103-tlinux kernel: __alloc_pages_nodemask+0x236/0x2a0Aug 2 00:55:46 VM-223-103-tlinux kernel: alloc_pages_current+0x6a/0xb0Aug 2 00:55:46 VM-223-103-tlinux kernel: __page_cache_alloc+0x6b/0xa0Aug 2 00:55:46 VM-223-103-tlinux kernel: filemap_fault+0x3a6/0x640Aug 2 00:55:46 VM-223-103-tlinux kernel: ext4_filemap_fault+0x31/0x50Aug 2 00:55:46 VM-223-103-tlinux kernel: __do_fault+0x38/0xb0Aug 2 00:55:46 VM-223-103-tlinux kernel: __handle_mm_fault+0xcc1/0x1030Aug 2 00:55:46 VM-223-103-tlinux kernel: handle_mm_fault+0xd1/0x1e0Aug 2 00:55:46 VM-223-103-tlinux kernel: __do_page_fault+0x200/0x500Aug 2 00:55:46 VM-223-103-tlinux kernel: do_page_fault+0x32/0x100Aug 2 00:55:46 VM-223-103-tlinux kernel: async_page_fault+0x45/0x50Aug 2 00:55:46 VM-223-103-tlinux kernel: RIP: 0033:0x923425Aug 2 00:55:46 VM-223-103-tlinux kernel: RSP: 002b:00007f0d30257d80 EFLAGS: 00010202Aug 2 00:55:46 VM-223-103-tlinux kernel: RAX: 00000000000038e4 RBX: 000000c0003fa600 RCX: 0000000000962d67Aug 2 00:55:46 VM-223-103-tlinux kernel: Mem-Info:Aug 2 00:55:46 VM-223-103-tlinux kernel: active_anon:16087067 inactive_anon:27297 active_file:1083 inactive_file:913 unevictable:0 dirty:1 writeback:0 slab_reclaimable:49598 slab_unreclaimable:29114 mapped:3640 shmem:68701 pagetables:46710 free:73341 free_pcp:2500 free_cma:0Aug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 Normal: free:32000kB min:30980kB low:93628kB high:156276kB active_anon:61887756kB inactive_anon:109188kB present:63963136kB managed:62648408kBAug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 DMA: 1*4kB (U) 0*8kB 0*16kB 0*32kB 2*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (M) 3*4096kB (M) = 15876kBAug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 DMA32: 3673*4kB (UME) 2532*8kB (UME) 1204*16kB (UE) 1630*32kB (UME) 941*64kB (UME) 414*128kB (UME) 84*256kB (ME) 5*512kB (UME) 0*1024kB 1*2048kB (H) 0*4096kB = 245700kBAug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 Normal: 1480*4kB (UME) 678*8kB (UME) 574*16kB (UME) 193*32kB (UME) 86*64kB (UM) 10*128kB (UM) 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 33488kBAug 2 00:55:46 VM-223-103-tlinux kernel: Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB
说明:以上日志截取了关键段落,省略了部分寄存器和重复字段。完整日志可通过
dmesg 命令获取。