确认 jvm 是否被 oom killer 杀死:执行 dmesg -t | grep -i "killed process",若输出含 killed process xxx (java) 且 anon-rss 接近或超物理内存总量,即为强证据;无输出需检查 kernel.dmesg_restrict 权限并查 journalctl 日志。

排查物理机内存超卖导致 JVM 进程被 OOM Killer 杀死,关键在于区分“整机内存真实耗尽”和“资源隔离失效下的伪超卖”——即宿主机通过虚拟化或容器技术过度分配内存,而内核无法感知上层限制,仍按全局视角触发 OOM。此时 JVM 往往是高 RSS、短生命周期、oom_score_adj 默认值的典型目标。
确认是否真被 OOM Killer 杀死
这是第一步,不能靠猜测:
- 执行 dmesg -T | grep -i "killed process",重点看输出中是否有类似
Killed process 12345 (java) total-vm:... anon-rss:...的行;anon-rss 值接近或超过宿主机物理内存总量,就是强证据 - 若无输出,检查权限:sudo sysctl kernel.dmesg_restrict,若为 1 则需临时放开:sudo sysctl kernel.dmesg_restrict=0
- 补充查日志:sudo journalctl -k --since "2 hours ago" | grep -E "(oom-killer|Out of memory)",尤其注意是否含
Memory cgroup out of memory—— 这说明是容器/VM 内存限额触达,而非宿主机全局耗尽
识别“超卖”痕迹:看内存水位与 cgroup 状态
超卖环境下,free -h 显示的可用内存常具欺骗性,需交叉验证:
- 运行 cat /proc/meminfo | grep -E "(MemAvailable|Committed_AS|CommitLimit)":
若Committed_AS > CommitLimit,说明内核已判定虚拟内存承诺过载,OOM 风险极高 - 检查是否启用 cgroup v1/v2:mount | grep cgroup;若存在
memory子系统,进入对应路径(如/sys/fs/cgroup/memory/xxx/)查看:
cat memory.usage_in_bytes 和 cat memory.limit_in_bytes —— 若 usage 接近 limit,且 JVM 在该 cgroup 下,就是超卖+限额共同作用 - 查内核水位:cat /proc/zoneinfo | grep -A5 "Node.*Normal" | grep "pages free",若
pages free极低(如 free -h 可能仍显示几百 MB “available”,因 page cache 未及时回收
聚焦 JVM 进程:排除误杀,定位真实内存压力源
JVM 被杀不等于它泄漏,更可能是超卖下它成了“最易杀对象”:
- 对比 anon-rss(dmesg 中给出)与 JVM 堆设定:
若 anon-rss 是-Xmx4g的 3 倍以上,大概率是堆外内存问题(DirectByteBuffer、JNI、JIT code cache、Metaspace 膨胀) - 用 jcmd $PID VM.native_memory summary(需启动时加
-XX:NativeMemoryTracking=detail)看各区域占比,重点关注Internal和Other是否异常增长 - 检查 GC 日志:
若频繁 Full GC 后仍无法释放大量内存,或Metaspace使用持续上升,说明类加载器泄漏;
若DirectMemory分配量远高于-XX:MaxDirectMemorySize设定,就是堆外泄漏 - 别只信 top RSS:用 smem -P java -c "pid user command pss uss anon-rss",PSS 比 RSS 更反映 JVM 对物理内存的真实贡献(剔除共享库重复计算)
验证与缓解:从宿主机层切断超卖链路
临时救火和长期治理要分开:
- 临时缓解:
立即挂载 swap(哪怕 2–4GB):sudo fallocate -l 4G /swapfile && sudo mkswap /swapfile && sudo swapon /swapfile;swap 不解决根本问题,但能缓冲突发申请,避免 OOM Killer 立即触发 - 调整内核参数防误杀:
降低 JVM 进程被选中的概率:echo -500 > /proc/$PID/oom_score_adj(注意:仅对当前进程有效,需在启动脚本中固化);
调低vm.min_free_kbytes(如 32GB 内存设为 32768),避免内核过早恐慌 - 根治超卖:
在虚拟化平台(如 KVM、VMware)或容器编排层(K8s)严格设置内存 request/limit,禁用 overcommit;
宿主机侧关闭透明大页:echo never > /sys/kernel/mm/transparent_hugepage/enabled(某些版本下它会加剧内存碎片,恶化 OOM 触发)











