必须快速响应、精准定位、最小化影响,核心是靠预设机制捕获现场、用数据驱动判断、按类型分路径处置:告警触发5分钟内摘流、查gc趋势、启用堆转储;依错误类型(heap/metaspace/thread/direct buffer/gc overhead)分路径排查;堆转储必看mat的leak suspects、histogram、path to gc roots;修复后需预发压测4小时验证并检查jvm参数合理性。

生产环境内存溢出(OOM)必须快速响应、精准定位、最小化影响。核心不是“等它崩”,而是靠预设机制捕获现场、用数据驱动判断、按类型分路径处置。
一、告警触发后立即执行的标准化动作
收到内存使用率≥90%或OOM日志告警,5分钟内完成以下操作:
- 将问题实例从负载均衡摘除,禁止新流量进入
- 确认JVM进程PID,执行jstat -gcutil
1000 3 ,快速查看GC频率与老年代占用趋势 - 检查是否已启用自动堆转储:运行jinfo -flag +HeapDumpOnOutOfMemoryError
,若未启用,立即补加并重启(仅限非核心服务) - 保留原始日志片段(含完整堆栈和时间戳),不覆盖、不清理任何日志文件
二、根据OOM错误类型选择排查路径
日志中明确的错误信息是第一判断依据,不同错误对应不同内存区域和根因方向:
- Java heap space → 重点查对象泄漏:静态集合、缓存无淘汰、ThreadLocal未清理、大对象堆积
- Metaspace → 重点查类加载行为:动态代理生成类过多、热部署未卸载类、Spring Boot DevTools残留
-
Unable to create new native thread → 查线程数与系统限制:jstack
| wc -l 对比 ulimit -u 和 -Xss 设置 - Direct buffer memory → 查NIO使用:Netty堆外内存泄漏、未调用cleaner.clean()或ByteBuffer.clear()
- GC overhead limit exceeded → 不是独立错误,是堆内存严重泄漏或碎片化的信号,需同步分析堆转储+GC日志
三、堆转储分析必须完成的三项关键动作
拿到.hprof文件后,不依赖直觉,只看三个MAT视图:
- 打开Leak Suspects Report,直接定位前2个高概率泄漏点(如“One instance of XXX dominates 82% of heap”)
- 查看Histogram,按“Objects”倒序,找数量异常多或单个实例超大的类(如byte[]、HashMap$Node、String)
- 对可疑类右键→Path to GC Roots → with all references,确认强引用链——重点看static、ThreadLocal、ClassLoader、监听器注册点
四、验证修复与上线前的强制检查项
代码修改后,不能直接上生产:
- 在同等配置的预发环境,用相同压测流量跑满4小时,监控老年代使用率是否稳定在60%以下
- 对比修复前后jstat -gc
输出,确保Full GC次数下降、每次耗时缩短、老年代回收量提升 - 检查JVM启动参数是否合理:-Xms与-Xmx设为相等(防动态扩容抖动),-XX:MaxMetaspaceSize不低于256m,-Xss不高于256k(除非明确需要大栈)
- 所有修复代码必须附带单元测试,覆盖该对象生命周期的创建→使用→释放全过程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











