欢迎光临
我们一直在努力

【JVM】OOM详解+JVM参数+FullGC排查+CPU飙高+死锁+内存泄漏+命令大全

大家好,我是程序员二叉。


简介

本文整合面试 + 线上实战全套 JVM 故障排查核心知识点:四大 OOM 类型成因、常用 JVM 参数、线上 OOM 标准排查流程、频繁 FullGC 定位方案、内存泄漏与内存溢出区别、CPU 飙高/线程死锁排查、JDK 工具命令、HeapDump 抓取与分析全流程,干货拉满。欢迎点赞关注收藏。


一、常见 4 种 OOM 类型及底层原因

1. 堆内存溢出(Java heap space)

报错: java.lang.OutOfMemoryError: Java heap space

核心原因:

  • 内存泄漏:无用对象持续被引用,GC 无法回收
  • 集合无限累加(List/Map 只增不减)
  • 一次性加载超大批量数据、未分页查询
  • -Xmx 最大堆内存设置过小

2. 元空间溢出(Metaspace)

报错: java.lang.OutOfMemoryError: Metaspace

核心原因:

  • 频繁动态生成 Class(CGLib、动态代理、SpringAOP)
  • 项目热部署、热加载频繁重复加载类
  • 大量反射、动态类加载场景
  • 配置了过小的 MaxMetaspaceSize

3. 栈溢出(StackOverflowError)

报错: java.lang.StackOverflowError

核心原因:

  • 方法无限递归调用
  • 递归深度过大
  • 线程栈 -Xss 设置过小

注意:栈溢出不属于 OOM,是线程栈帧溢出异常

4. 直接内存溢出(Direct buffer memory)

报错: java.lang.OutOfMemoryError: Direct buffer memory

核心原因:

  • NIO 使用 allocateDirect() 频繁分配直接内存
  • 直接内存未手动释放
  • 不受 -Xmx 限制,耗尽系统物理内存导致溢出

二、高频 JVM 参数详解(面试必背)

参数作用说明
-Xms 初始堆内存大小,建议与 Xmx 一致
-Xmx 最大堆内存大小
-Xss 单个线程栈内存大小
-Xmn 新生代整体内存大小
-XX:MetaspaceSize 元空间初始值
-XX:MaxMetaspaceSize 元空间最大值,防止类加载OOM
-XX:MaxDirectMemorySize 限制NIO直接内存上限
-XX:+HeapDumpOnOutOfMemoryError OOM时自动导出堆快照
-XX:HeapDumpPath 指定dump文件存放路径
-XX:+PrintGCDetails 打印详细GC日志

三、线上 OOM 完整排查流程(标准实战流程)

  • 提前配置JVM参数:OOM自动dump快照
  • 服务崩溃后获取 .hprof 堆文件
  • 使用 MAT / VisualVM / JProfiler 打开分析
  • 查看大对象、实例数量、集合占用Top
  • 追踪 GC Roots 引用链,定位无法回收对象
  • 排查代码:静态集合累积、ThreadLocal未清理、IO未关闭、内存泄漏
  • 代码优化:分页、手动释放、移除长引用
  • 压测验证问题修复

  • 四、频繁 Full GC 完整排查步骤

    线上90%频繁FullGC = 内存泄漏

  • jstat -gc PID 1000 实时观察GC变化
  • 发现老年代持续上涨、频繁FullGC
  • 查看GC日志,确认是空间不足/元空间满/手动GC
  • dump堆快照分析存活大对象
  • 定位长期累积无法回收的集合/对象
  • 优化方案:
    • 修复内存泄漏
    • 批量查询分页处理
    • 减少大对象创建
    • 合理调优堆、元空间大小

    五、内存泄漏 VS 内存溢出(高频面试)

    1. 内存泄漏(Memory Leak)

    • 定义:对象已无用,但存在有效引用,GC无法回收
    • 本质:对象占着内存不释放
    • 后果:内存缓慢上涨,最终触发OOM

    典型泄漏场景:

    • static 静态集合缓存无限累加
    • ThreadLocal 使用不 remove
    • 连接、IO 流不关闭
    • 长生命周期持有短生命周期对象引用

    2. 内存溢出(OOM)

    • 定义:JVM 内存资源耗尽,无法分配新对象
    • 本质:内存不够用

    核心关系

    内存泄漏是根源,内存溢出是最终结果


    六、线上 CPU 飙高排查流程(生产万能套路)

  • top 找到 CPU 100% 的 Java 进程 PID
  • top -Hp PID 查看进程内最耗CPU线程TID
  • printf "%x TID" 转为 16进制
  • jstack PID | grep 16进制ID -A30
  • 精准定位业务代码行
  • 常见原因:

    • 代码死循环
    • 复杂逻辑运算、大数据遍历
    • 频繁GC、内存抖动
    • 锁自旋、线程竞争

    七、线程死锁排查方法

  • jps 获取Java进程号
  • jstack PID 打印线程快照
  • 检索关键字:deadlock、waiting to lock、locked
  • jstack 自动输出死锁线程 + 代码行数
  • 调整锁顺序、加锁超时解决

  • 八、JVM 五大排查命令作用总结

    jps

    查看所有Java进程PID,基础排查入口

    jstack

    线程问题神器:排查死锁、CPU飙高、线程阻塞、线程卡死

    jmap

    内存问题神器:查看堆使用、实例数量、导出dump文件

    jstat

    GC神器:实时监控新生代、老年代、GC次数、GC耗时

    jhat

    JDK内置dump分析工具(现已淘汰,用MAT)


    九、堆 Dump 抓取 + 分析完整实战

    1. 手动抓取dump

    jmap -dump:format=b,file=heap.hprof PID

    2. 线上自动抓取(推荐配置)

    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=/data/dump/

    3. MAT 分析步骤

  • 打开 hprof 文件
  • Histogram:查看对象数量排行
  • Dominator Tree:查看大对象占用排行
  • 追踪 GC Root 定位泄漏源头
  • 精准修复代码问题

  • 十、全文核心总结(面试速背)

  • 四类 OOM:堆溢出、元空间溢出、栈溢出、直接内存溢出
  • 内存泄漏:对象无用不释放,是线上 OOM 最大元凶
  • CPU 飙高排查链路:top → top -Hp → 16 进制 → jstack
  • FullGC 频繁:绝大多数是内存泄漏导致
  • OOM 排查核心:dump 快照 + MAT 分析 GC Roots 引用链
  • 常用参数:Xms/Xmx 堆、Xss 栈、Metaspace 元空间
  • 直接内存:不受堆限制,物理内存满照样 OOM
  • 赞(0)
    未经允许不得转载:171主机测评 » 【JVM】OOM详解+JVM参数+FullGC排查+CPU飙高+死锁+内存泄漏+命令大全
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址