TencentOS Server OOM Killer 分析与处理

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

相关产品
TencentOS Server 产品页,含版本规格、价格与购买入口。

一、OOM 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

20、升级实例规格

当业务负载确实超出当前实例的内存容量,且无法通过应用层优化(如修复内存泄漏、调整缓存策略)解决时,可考虑升级实例规格以增加可用内存:

# 查看当前实例内存规格free -h# 查看内核识别的物理内存总量grep MemTotal /proc/meminfo

在腾讯云控制台或通过 API 调整实例规格时,建议注意以下事项:

·升级实例规格通常需要重启实例,请提前做好业务切换和应急预案。

·部分实例类型支持在线变配(无需停机),具体支持的类型以云服务器产品文档为准。

·升级前建议先排查是否存在内存泄漏或配置不当,避免仅通过扩容掩盖问题。

21、监控告警

建议对以下指标设置告警:

·可用内存低于总内存 10%

·oom-killer 事件出现次数 > 0

·进程 RSS 接近系统内存总量

# 快速检查是否曾有 OOM 事件dmesg -T | grep -c "oom-killer"

22、附录:完整 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 命令获取。

赞 (0)
上一篇 4天前
下一篇 4天前