JVM性能监控与故障排查工具详解

一、命令行工具
1. 工具概览
工具 核心功能 使用场景 关键字
jps 查看Java进程列表 快速定位目标进程 进程ID、主类名
jstack 生成线程栈快照 死锁分析、线程阻塞、CPU高占用 线程状态、锁持有、死锁检测
jmap 生成堆转储、查看内存使用 内存泄漏、大对象分析、堆内存结构 堆转储、对象统计、类加载
jstat 监控JVM统计信息 GC频率、内存使用、类加载情况 GC时间、内存使用率、类加载数
jinfo 查看/修改JVM配置 动态调整JVM参数、查看运行时配置 系统属性、JVM参数、动态修改
2. 核心工具详解

jps(Java Process Status)

  • 功能:列出当前运行的Java进程,显示进程ID和主类名

  • 常用命令 :

    bash 复制代码
    jps -l # 显示完整主类名
    jps -v # 显示JVM启动参数
    jps -m # 显示主类的传入参数
  • 使用场景:快速定位目标Java进程,获取进程ID

jstack(Java Stack Trace)

  • 功能:生成线程栈快照,用于分析线程状态、死锁、阻塞等问题

  • 常用命令 :

    bash 复制代码
    jstack <pid> # 生成线程栈快照
    jstack -l <pid> # 显示锁信息(死锁分析必备)
    jstack -F <pid> # 强制生成快照(进程无响应时)
  • 面试题:如何使用jstack分析死锁?
    回答步骤 :

    1. 使用jps获取目标进程ID

    2. 执行jstack -l <pid> > jstack.log生成线程栈快照

    3. 搜索日志中的Found one Java-level deadlock关键字

    4. 分析死锁线程的锁持有情况,定位死锁原因
      示例输出:

      Found one Java-level deadlock:

      "Thread-1":
      waiting for ownable synchronizer 0x000000076b600580, (a java.util.concurrent.locks.ReentrantLockNonfairSync), which is held by "Thread-0" "Thread-0": waiting for ownable synchronizer 0x000000076b6005b8, (a java.util.concurrent.locks.ReentrantLockNonfairSync),
      which is held by "Thread-1"

jmap(Java Memory Map)

  • 功能:生成堆转储文件、查看堆内存使用情况

  • 常用命令 :

    bash 复制代码
    jmap -dump:format=b,file=heap.hprof <pid> # 生成堆转储
    jmap -histo <pid> # 显示对象统计信息(类名、实例数、内存占用)
    jmap -histo:live <pid> # 显示存活对象统计信息
    jmap -heap <pid> # 显示堆内存结构
  • 使用场景:内存泄漏分析、大对象定位、堆内存结构查看

jstat(Java Statistics Monitoring)

  • 功能:监控JVM运行时统计信息,包括GC、内存、类加载等

  • 常用命令 :

    bash 复制代码
    jstat -gc <pid> <interval> <count> # 监控GC情况,每interval毫秒输出一次,共count次
    jstat -gcutil <pid> # 显示GC利用率(百分比)
    jstat -class <pid> # 显示类加载情况
    jstat -compiler <pid> # 显示JIT编译情况
  • 输出示例 :

    复制代码
    S0C    S1C    S0U    S1U      EC       EU        OC         OU       MC     MU    CCSC   CCSU   YGC     YGCT    FGC    FGCT     GCT   
    0.0   1024.0  0.0    0.0   8192.0   1024.0   20480.0     5120.0   5120.0 1024.0 512.0   128.0      5    0.020   1      0.050    0.070

jinfo(Java Configuration Info)

  • 功能:查看和修改JVM配置参数

  • 常用命令 :

    bash 复制代码
    jinfo <pid> # 显示JVM参数和系统属性
    jinfo -flags <pid> # 显示JVM启动参数
    jinfo -sysprops <pid> # 显示系统属性
    jinfo -flag <name> <pid> # 查看单个JVM参数值
    jinfo -flag +<name> <pid> # 开启JVM参数(布尔类型)
    jinfo -flag -<name> <pid> # 关闭JVM参数(布尔类型)
  • 使用场景:动态调整JVM参数、查看运行时配置

二、可视化工具
1. 工具对比
工具 功能全面性 使用难度 线上可用性 核心优势
JConsole 基础 低 可远程连接 内置JDK,轻量级
VisualVM 全面 中 可远程连接 功能丰富,插件扩展
Arthas 强大 中 高(无需重启) 线上诊断利器,动态注入
2. 核心工具详解

JConsole

  • 启动方式 :jconsole 或 JDK/bin/jconsole.exe
  • 核心功能 :
    • 内存监控:堆内存、非堆内存使用情况
    • 线程监控:线程状态、死锁检测
    • GC监控:GC频率、时间
    • 类加载监控:类加载数、卸载数
  • 使用场景:基础监控,适合开发测试环境

VisualVM

  • 启动方式 :jvisualvm 或 JDK/bin/jvisualvm.exe
  • 核心功能 :
    • 内存分析:堆转储分析、大对象定位
    • 线程分析:线程栈快照、死锁检测
    • GC分析:GC日志分析、内存泄漏检测
    • 抽样器:CPU抽样、内存抽样
    • 插件扩展:支持多种插件,如MAT集成、JProfiler集成
  • 使用场景:功能全面的监控和分析工具,适合开发测试和生产环境

Arthas

  • 核心功能:线上诊断利器,无需重启应用

  • 启动方式:

    bash 复制代码
    curl -O https://arthas.aliyun.com/arthas-boot.jar
    java -jar arthas-boot.jar <pid>
  • 常用命令:

    • dashboard:实时监控面板(CPU、内存、线程)
    • thread:线程状态分析,死锁检测
    • heapdump:生成堆转储
    • jad:反编译类
    • watch:方法执行监控
    • trace:方法调用链路追踪
    • redefine:热更新代码
  • 面试题:如何使用Arthas排查线上问题?
    回答模板 :

    Arthas是线上诊断利器,可通过以下步骤排查问题:

    1. 连接目标进程:

      bash 复制代码
      java -jar arthas-boot.jar <pid>
    2. 实时监控状态:

      bash 复制代码
      dashboard # 查看CPU、内存、线程实时状态
    3. 分析CPU高占用:

      bash 复制代码
      thread -n 3 # 查看CPU占用前3的线程
      thread <tid> # 查看具体线程栈
    4. 分析内存问题:

      bash 复制代码
      heapdump /tmp/heap.hprof # 生成堆转储
      jad <className> # 反编译类,查看代码
    5. 监控方法执行:

      bash 复制代码
      watch <className> <methodName> "{params, returnObj}" -x 2 # 监控方法参数和返回值
      trace <className> <methodName> # 追踪方法调用链路
    6. 热更新代码:

      bash 复制代码
      redefine <classFile> # 热更新类文件
    7. 死锁检测:

      bash 复制代码
      thread -b # 查看阻塞线程
      thread -d # 检测死锁

    Arthas的核心优势是无需重启应用,适合线上环境诊断,可快速定位和解决问题。

三、堆转储分析工具
1. 工具对比
工具 类型 核心功能 优势 适用场景
MAT(Memory Analyzer Tool) 开源 内存泄漏分析、大对象定位 免费、内存泄漏检测强大 内存泄漏分析、大对象定位
JProfiler 商业 全面的性能分析 功能强大、易用性高、实时监控 内存分析、CPU分析、线程分析
2. MAT(Memory Analyzer Tool)
  • 核心功能 :
    • 内存泄漏检测:通过支配树、直方图等分析内存泄漏
    • 大对象定位:快速找到占用内存最多的对象
    • 引用关系分析:查看对象间的引用链
    • 线程分析:查看线程栈和锁信息
  • 使用步骤 :
    1. 使用jmap -dump:format=b,file=heap.hprof <pid>生成堆转储
    2. 启动MAT,打开堆转储文件
    3. 运行"Leak Suspects Report"分析内存泄漏
    4. 查看"Histogram"分析对象统计信息
    5. 查看"Dominator Tree"分析对象支配关系
  • 核心报告 :
    • Leak Suspects:内存泄漏嫌疑报告
    • Histogram:对象数量和大小统计
    • Dominator Tree:对象支配树,显示对象的内存支配关系
    • Path to GC Roots:对象到GC Roots的引用链
3. JProfiler
  • 核心功能 :
    • 内存分析:堆内存使用情况、对象引用关系
    • CPU分析:方法调用次数、耗时统计
    • 线程分析:线程状态、死锁检测
    • 热点方法分析:找出耗时最多的方法
    • 实时监控:实时监控JVM运行状态
  • 使用场景:商业项目的性能分析,功能全面,易用性高
四、工具使用最佳实践
1. 日常监控
  • 使用jstat定期监控GC情况,及时发现内存问题
  • 使用JConsole 或VisualVM进行实时监控
  • 线上环境建议开启GC日志,便于后续分析
2. 故障排查流程
  1. 定位问题:

    • CPU高:使用top+jstack分析线程栈
    • 内存泄漏:使用jmap生成堆转储,MAT分析
    • 线程阻塞:使用jstack分析线程状态
    • 死锁:使用jstack -l或Arthas thread -d检测
  2. 分析问题:

    • 查看线程栈中的锁持有情况
    • 分析堆转储中的大对象和引用关系
    • 结合GC日志分析GC频率和时间
  3. 解决问题:

    • 代码优化:修复死锁、减少对象创建
    • JVM参数调整:调整堆大小、GC收集器
    • 资源优化:释放无用资源、优化缓存策略
3. 线上环境注意事项
  • 使用Arthas进行线上诊断,避免影响应用性能
  • 生成堆转储时注意:
    • 堆转储文件较大,建议输出到磁盘空间充足的目录
    • 生成堆转储会暂停应用(约几秒到几十秒),建议在低峰期执行
    • 可使用jmap -dump:live只生成存活对象,减少文件大小
五、面试题汇总
1. 如何使用jstack分析死锁?

回答:

  1. 使用jps获取目标进程ID
  2. 执行jstack -l <pid> > jstack.log生成线程栈快照
  3. 搜索日志中的Found one Java-level deadlock关键字
  4. 分析死锁线程的锁持有情况:
    • 查看线程状态(BLOCKED)
    • 查看"waiting for ownable synchronizer"(等待的锁)
    • 查看"locked"(已持有的锁)
  5. 定位死锁原因:两个或多个线程相互持有对方需要的锁
2. 如何使用Arthas排查线上问题?

回答:

  1. 连接目标进程:java -jar arthas-boot.jar <pid>
  2. 使用dashboard查看实时状态,定位异常指标(CPU、内存、线程)
  3. 根据异常指标选择对应命令:
    • CPU高:thread -n 3查看CPU占用前3的线程
    • 内存问题:heapdump生成堆转储,结合MAT分析
    • 方法执行异常:watch监控方法参数和返回值,trace追踪调用链路
    • 死锁:thread -d检测死锁
  4. 如需代码修复,使用jad反编译类,redefine热更新代码
  5. 问题解决后,使用quit退出Arthas
3. 如何分析内存泄漏?

回答:

  1. 使用jstat -gc <pid>监控GC情况,观察老年代内存是否持续增长
  2. 使用jmap -histo:live <pid>查看存活对象统计,定位大对象
  3. 使用jmap -dump:format=b,file=heap.hprof <pid>生成堆转储
  4. 使用MAT分析堆转储:
    • 运行"Leak Suspects Report"查找内存泄漏嫌疑
    • 查看"Dominator Tree"分析对象支配关系
    • 查看"Path to GC Roots"分析对象引用链
  5. 定位内存泄漏源:找出长期存活的对象和导致其无法回收的引用链

总结

JVM性能监控与故障排查工具是Java开发者必备技能,不同工具适用于不同场景:

  • 命令行工具:轻量级、适合快速定位问题
  • 可视化工具:功能全面、适合深入分析
  • Arthas:线上诊断利器、无需重启应用
  • 堆转储分析工具:内存泄漏分析的核心工具

掌握这些工具的使用方法,结合具体业务场景进行调优,能够有效提升应用性能和稳定性。

相关推荐
今天的砖头有点烫手啊1 小时前
GC 算法与垃圾收集器演进:从 Serial 到 ZGC
java·jvm
johnny2331 小时前
JVM生态下Web开发框架:SparkJava、Javalin、Micronaut、SparkKotlin
jvm
晨小安11 小时前
ThreadLocal及其内存泄漏问题深度解析
java·jvm·tomcat·哈希表
jingli918 小时前
一个测试用例把连接池卡死 30 秒:SQLite 连接池 max_size=1 下的重入自锁复盘
jvm·sqlite·测试用例
imDwAaY1 天前
Java中垃圾回收器 G1 和 CMS 有什么区别?
jvm·后端
xiaoqiMikko1 天前
JVM 线上排查实战(五):升 JDK 17 后进程起不来,十几个老 GC 参数挨个实测(完结)
java·jvm
Flynt1 天前
Java 27 悄悄改了 3 个默认值,我在 1 核小机器上逐个验证了一遍
java·jvm·性能优化
xiaoqiMikko1 天前
JVM 线上排查实战(三):grep BLOCKED 找不到的死锁,和 jstack 根本不报的死锁
java·jvm
此时不提桶,更待何时7 天前
01-06-A-JVM排查实战详解
java·jvm
wuminyu7 天前
HotSpot的轻量锁与膨胀后的ObjectMonitor状态重建原理
java·linux·c语言·jvm·c++