图解JVM - 19.JVM监控及诊断工具-命令行篇

发布于:2025-03-11 ⋅ 阅读:(29) ⋅ 点赞:(0)

1. 概述

在JVM性能调优和故障排查中,命令行工具是开发运维人员最锋利的"手术刀"。如图1所示,这些工具可以分为三类:

核心工具家族

  • 进程定位:jps
  • 运行时监控:jstat
  • 参数管理:jinfo
  • 内存分析:jmap/jhat
  • 线程分析:jstack
  • 全能工具:jcmd
  • 远程诊断:jstatd

2. jps:查看正在运行的Java进程

2.1 基础用法

$ jps
1234 Jps
5678 Main
9101 Worker

2.2 参数详解

典型应用场景

  • 快速定位应用PID
  • 验证JVM参数是否生效
  • 检查多个Java进程的启动配置

3. jstat:查看JVM统计信息

3.1 监控GC活动

$ jstat -gcutil 5678 1000 5
S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
0.00  99.99  63.78  29.87  95.34  92.10    135    2.017     5    0.987    3.004

3.2 内存分区监控

关键指标解读

  • YGC/YGCT:年轻代GC次数/耗时
  • FGC/FGCT:老年代GC次数/耗时
  • GCT:总GC耗时

4. jinfo:实时查看和修改JVM配置参数

4.1 参数查看实战

$ jinfo 5678 
Attaching to process ID 5678, please wait...
VM Arguments:
java.awt.headless=true
-Xms1024m
-Xmx2048m
-XX:MaxMetaspaceSize=256m

4.2 动态修改参数

典型修改案例

  • 调整日志级别:<font style="background-color:rgb(252, 252, 252);">jinfo -flag +PrintGC 5678</font>
  • 关闭JMX:<font style="background-color:rgb(252, 252, 252);">jinfo -flag -Dcom.sun.management.jmxremote 5678</font>

注意:仅支持修改<font style="background-color:rgb(252, 252, 252);">manageable</font>类型的参数(可通过<font style="background-color:rgb(252, 252, 252);">java -XX:+PrintFlagsFinal | grep manageable</font>查询)

5. jmap:导出内存映像文件&内存使用情况

5.1 内存快照生成

# 生成堆转储文件
$ jmap -dump:format=b,file=heap.hprof 5678

# 实时内存统计
$ jmap -histo:live 5678 | head -n 10
 num     #instances         #bytes  class name
----------------------------------------------
   1:         23456       13421728  [B
   2:         12345        5678900  java.lang.String
   3:          6789        3456780  java.util.HashMap$Node

5.2 内存泄漏分析实战

关键诊断步骤

  1. 使用<font style="background-color:rgb(252, 252, 252);">-histo</font>查看大对象分布
  2. 生成堆转储文件进行深度分析
  3. 对比多次dump文件观察对象增长

6. jhat:JDK自带堆分析工具

6.1 基础分析流程

$ jhat -port 7000 heap.hprof
Reading from heap.hprof...
Snapshot resolved.
Server is ready on http://localhost:7000/

6.2 分析界面解读

核心功能

  • 对象直方图查询
  • 对象引用链追踪
  • 根集可达性分析

注意:生产环境建议使用MAT或VisualVM替代,jhat适合快速分析

7. jstack:打印JVM中线程快照

7.1 线程状态解析

7.2 死锁检测示例

$ jstack 5678 | grep -A 10 deadlock
"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f48740c4800 nid=0x5e03 waiting for monitor entry [0x00007f486b5fe000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.example.DeadlockDemo.methodB(DeadlockDemo.java:25)
        - waiting to lock <0x000000076ab00000> 
        - locked <0x000000076ab00010> 

"Thread-0" #11 prio=5 os_prio=0 tid=0x00007f48740c3000 nid=0x5e02 waiting for monitor entry [0x00007f486b6ff000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at com.example.DeadlockDemo.methodA(DeadlockDemo.java:15)
        - waiting to lock <0x000000076ab00010> 
        - locked <0x000000076ab00000>

线程分析技巧

  • 使用<font style="background-color:rgb(252, 252, 252);">top -Hp PID</font>找到高CPU线程
  • 将线程ID转换为16进制:<font style="background-color:rgb(252, 252, 252);">printf "%x\n" 12345</font>
  • 在jstack输出中搜索nid对应的线程

8. jcmd:多功能命令行

8.1 全能工具剖析

8.2 常用命令实战

# 列出所有可用诊断命令
$ jcmd 5678 help

# 获取JVM启动参数
$ jcmd 5678 VM.flags

# 强制触发Full GC
$ jcmd 5678 GC.run

# 生成堆转储文件(替代jmap)
$ jcmd 5678 GC.heap_dump filename=heap.hprof

功能对比表

功能 jcmd命令 传统工具
线程快照 Thread.print jstack
堆转储 GC.heap_dump jmap -dump
类加载统计 GC.class_histogram jmap -histo
JFR记录 JFR.start/JFR.dump 需单独配置

9. jstatd:远程主机信息收集

9.1 远程监控架构

9.2 安全配置步骤

  1. 创建安全策略文件
grant codebase "file:${java.home}/../lib/tools.jar" {
    permission java.security.AllPermission;
};
  1. 启动jstatd服务
$ jstatd -J-Djava.security.policy=jstatd.policy -p 1099
  1. 远程连接验证
$ jps 192.168.1.100:1099

生产环境建议

  • 使用VPN或SSH隧道进行加密传输
  • 限制访问IP地址范围
  • 定期轮换安全证书

10. 常见问题与解决方案

10.1 经典问题排查矩阵

现象 诊断工具 关键操作步骤
Java进程突然消失 jps + 系统日志 1. 检查OOM Killer日志 2. 分析hs_err_pid.log 3. 监控系统资源使用
内存持续增长 jstat + jmap 1. 观察GC频率变化 2. 生成堆转储对比 3. MAT分析对象引用链
线程池阻塞 jstack + top 1. 定位BLOCKED状态线程 2. 分析锁竞争关系 3. 检查线程等待条件
FullGC频繁 jstat + jinfo 1. 检查内存分配比例 2. 分析对象晋升策略 3. 调整SurvivorRatio参数
类加载失败 jcmd + verbose日志 1. 查看ClassLoader统计 2. 检查元空间使用 3. 分析依赖冲突

10.2 内存溢出(OOM)实战

关键配置参数

-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/path/to/dumps
-XX:OnOutOfMemoryError="kill -9 %p"  # 自动清理进程

11. 高频面试问题与解答

11.1 工具原理类

Q1:jstat和jmap的本质区别是什么?

  • jstat通过JMX接口获取实时统计值,采样周期可配置
  • jmap需要挂起线程生成完整堆快照,会产生STW停顿

Q2:线上环境如何安全使用jstack?

  • 避免直接执行<font style="background-color:rgb(252, 252, 252);">kill -3</font>可能破坏标准输出
  • 配合<font style="background-color:rgb(252, 252, 252);">-F</font>参数强制获取线程快照
  • 多次采样对比(建议至少3次)
  • 优先使用jcmd Thread.print命令

11.2 实战操作类

Q3:如何快速定位CPU飙高问题?

# 1. 定位高CPU进程
top -c

# 2. 转换线程ID为16进制
printf "%x\n" 12345

# 3. 抓取线程栈并分析
jcmd 5678 Thread.print | grep nid=0x3039 -A 15

Q4:Metaspace溢出有哪些排查手段?

  1. <font style="background-color:rgb(252, 252, 252);">jstat -gcmetacapacity</font> 查看元空间使用
  2. <font style="background-color:rgb(252, 252, 252);">jcmd GC.class_stats</font> 统计类加载详情
  3. 使用arthas的classloader命令分析
  4. 添加<font style="background-color:rgb(252, 252, 252);">-XX:NativeMemoryTracking=detail</font>参数

11.3 高级调优类

Q5:G1回收器应该关注哪些jstat指标?

Q6:如何诊断Direct Memory泄漏?

  1. <font style="background-color:rgb(252, 252, 252);">jmap -histo:live</font> 查找ByteBuffer实例
  2. 添加<font style="background-color:rgb(252, 252, 252);">-XX:MaxDirectMemorySize</font>限制大小
  3. 使用NMT监控本地内存:
jcmd 5678 VM.native_memory detail.diff

全工具速查手册

最佳实践建议

  1. 生产环境必备诊断命令:
alias jvmdiag="jcmd PID VM.flags; jstat -gcutil PID 1000 3; jstack PID"
  1. 建立标准化检查清单:
  • 内存使用趋势图
  • GC频率/耗时记录
  • 线程状态分布统计
  • 类加载/卸载数量监控

通过系统掌握这些命令行工具,开发者可以快速构建起立体化的JVM诊断能力,无论是应对突发的线上故障,还是进行深度的性能调优,都能做到有的放矢、游刃有余。建议在日常开发中定期执行健康检查,形成"预防为主,快速定位"的运维体系。


网站公告

今日签到

点亮在社区的每一天
去签到