内存不足崩溃需区分oom kill与内核panic:前者留out of memory日志并生成core file(用gdb分析堆/映射),后者触发kernel panic并依赖vmcore(用crash工具查log/mem/vm);辅以/proc/meminfo、smem、cgroup指标交叉验证真实内存压力。
内存不足导致的系统崩溃,通常不会留下常规日志或可复现的程序行为,而是触发内核 oom killer 或直接 panic。这时真正有效的证据不是应用日志,而是内存转储(vmcore 或 core dump)——它能告诉你“崩溃前内存到底被谁占光了”。排查关键在于分清两类转储:用户态进程崩溃产生的 core file(用 gdb 分析),和内核级崩溃生成的 vmcore(用 crash 工具分析)。下面按实际排查路径展开。
先确认崩溃类型:是 OOM Kill 还是内核 panic
查看 /var/log/messages 或 dmesg -T 输出:
- 出现 Out of memory: Kill process + 进程名 + score 值 → 是 OOM Killer 主动终止进程,属于内存不足引发的用户态服务崩溃,对应分析 core file 或进程内存快照
- 出现 Kernel panic、Unable to handle kernel NULL pointer dereference 或 BUG: unable to handle kernel paging request → 是内核自身崩溃,必须依赖 vmcore 分析
- 若两者都无,但系统突然重启且无明显日志,需检查是否启用了 kdump 但转储失败(如 /var/crash/ 为空或大小为 0)
查 OOM 场景下的 core file:定位“吃内存大户”
当某个进程被 OOM Killer 杀掉,且该进程开启了 core dump,系统会生成一个 core 文件(如 core.12345)。用 gdb 加载后重点看三件事:
- 执行 info proc mappings:查看进程虚拟内存布局,重点关注 [heap] 和大块 anon 映射区域,判断是否堆内存持续增长
- 执行 info files 确认加载的符号信息是否完整;若缺失调试信息,需用带 -g 编译的二进制重试
- 结合 bt full 和 frame N 切换栈帧,检查崩溃前是否在分配内存(如 malloc、new、mmap)、是否反复 realloc 未释放
查内核 panic 的 vmcore:确认内存耗尽是否诱发了内核异常
vmcore 是内存快照本身,必须配合对应内核的 vmlinux(带调试符号)才能解析。常用命令:
- crash vmlinux vmcore 进入交互环境后,运行 log | tail -20 查看 panic 前最后几条内核日志,确认是否含 Page allocation failure、slab_out_of_memory 等线索
- 运行 mem 查看物理内存总体使用状态;foreach pgrep 可列出所有进程占用页数,配合 ps -G 找出高 RSS 进程
- 运行 vm -v 查看各内存区域(DMA、Normal、HighMem)剩余页数;若 Normal zone free_pages 接近 0,说明内核无法分配中等大小连续页,常是 slab 泄漏或 pagecache 挤占所致
辅助验证:从系统层面交叉印证内存压力
转储文件只是“快照”,需结合运行时指标还原背景:
- 检查 /proc/meminfo 中的 MemAvailable(非 MemFree)是否长期低于 100MB;SwapCached 高 + pgpgin/pgpgout 持续上升,说明频繁换入换出
- 用 smem -w 查看 USS(唯一驻留集),排除缓存干扰;USS 长期增长的进程大概率存在内存泄漏
- 若使用容器,检查 cgroup v1 的 /sys/fs/cgroup/memory/xxx/memory.usage_in_bytes 或 cgroup v2 的 memory.current,确认是否触发了 memory.limit_in_bytes 限制











