在日常开发和运维过程中,我们常常会遇到各种各样的疑难杂症,比如 CPU 占用过高、内存溢出、接口响应超时、程序异常、GC 频繁等等。对于一个合格的 Java 开发人员来说,熟练地运用各种工具对这些问题进行排查是基本技能。这篇文章主要对 JDK 内置的一些常用的 JVM 工具做一个汇总,方便我们对 Java 应用进行问题诊断、代码调试或性能分析。
在 JDK 中自带了很多实用的命令行工具可以帮助开发人员解决 Java 应用的疑难杂症,这些工具位于 JDK 的 bin 目录下:
尽管这些工具看上去都是 .exe
可执行文件,实际上它们只是 Java 程序的一层包装,真正的实现位于 tools.jar
中:
所以当我们执行 jps.exe
命令的时候,和执行 java -classpath %JAVA_HOME%/lib/tools.jar sun.tools.jps.Jps
是完全一样的。正因为此,我们在查看 jstat
、jmap
和 jhat
等命令的使用帮助时,可以看到一个 -J<flag>
参数,这个参数用于指定 JVM 参数,比如 -J-Xmx512m
可以限定程序使用的最大堆内存。
不过要注意的是,在 JDK 9 之后,tools.jar
文件已经没有了,而是增加了一个 jmods
目录,之前的工具类可以通过引入模块来加载:
$ java --add-modules jdk.jcmd sun.tools.jps.Jps
下面对这些命令行工具的用法做一个简单的总结:
- jps - JVM Process Status Tool
- jinfo - Configuration Info for Java
- jstat - JVM Statistics Monitoring Tool
- jmap - Memory Map for Java
- jhat - JVM Heap Analysis Tool
- jstack - Stack Trace for Java
- jcmd - JVM Diagnostic Commands Tool
- jstatd - JVM jstat Daemon
- jsadebugd - Serviceability Agent Debug Daemon for Java
- jdb - The Java Debugger
- jhsdb - Java HotSpot Debugger
有一些诊断工具比较特殊,它们并不是可执行文件,而是 JVM 内置的,或者以 Java Agent 的形式存在。
- jmx - Java Management Extensions Agent
- jdwp - Java Debug Wire Protocol
- hprof - A Heap/CPU Profiling Tool
除了命令行工具,JDK 还提供了一些图形化的监控工具方便观察 Java 应用的运行情况,可以非常直观地对程序的内存、线程、类加载等进行分析。
- jconsole - A JMX-compliant graphical tool for monitoring a Java virtual machine
- jmc - JRocket Mission Control
- jvisualvm - Java VisualVM
- JDK Tools and Utilities
- Java问题诊断和排查工具
- JVM监控和诊断工具
- Java自带的各类型命令工具
- JVM监控及诊断工具-GUI上篇
- 史上最全图详解Jvm—诊断工具和JVM监控
- JVM问题诊断快速入门
- JVM性能调优-命令行工具jps/jstat/jinfo/jmap/jhat/jstack/jcmd
- 展開JDK工具的30天應用之旅 系列
- JVM 性能调优监控工具 jps、jstack、jmap、jhat、jstat、hprof 使用详解
- jvm 性能调优工具之 jcmd
除了 JDK 自带的工具,还有一些开源的 JVM 诊断工具提供了更为丰富和强大的功能:
- Arthas
- vjtools
- bistoury
- XPocket
- patric-r/jvmtop - Java monitoring for the command-line, profiler included
- Native Memory Tracking 详解(1):基础介绍
- Native Memory Tracking 详解(2):追踪区域分析(一)
- Native Memory Tracking 详解(3):追踪区域分析(二)
- Native Memory Tracking 详解(4):使用 NMT 协助排查内存问题案例
- 聊聊HotSpot VM的Native Memory Tracking
- JVM 堆外内存泄漏分析(一)
- JVM 堆外内存泄漏分析(二)
- Java内存之本地内存分析神器: NMT 和 pmap
- 一次完整的JVM NativeMemoryTracking 堆外内存泄露分析
uptime
top
- 显示系统统计信息和进程信息top -Hp [PID]
- 显示线程信息
vmstat
- 统计 CPU、内存使用情况、swap 使用情况等iostat
- 显示磁盘 I/O 使用情况gdb
ldd
lsof
ps
pstack
strace
ipcs
free
sar
readelf
objdump
nm
size
gprof
nmon
valgrind
asan
- CPU load 飙高
- 定位到 pid -> tid -> jstack 线程堆栈
- OOM
- 配置自动 dump -> MAT 分析
- 定位到哪个空间 OOM
- GC 频繁
- 打开 gc 日志
- jstat 查看并分析 gc 日志
- 服务无响应、响应超时、宕机
- 报 404、500、502、503、504 错误
- 分析 GC 日志
- Young GC 日志
- [GC [PSYoungGen: 274931K->10738K(274944K)] 371093K->147186K(450048K), 0.0668480 secs] [Times: user=0.17 sys=0.08, real=0.07 secs]
- Full GC 日志
- [Full GC [PSYoungGen: 10738K->0K(274944K)] [ParOldGen: 136447K->140379K(302592K)] 147186K->140379K(577536K) [PSPermGen: 85411K->85376K(171008K)], 0.6763541 secs] [Times: user=1.75 sys=0.02, real=0.68 secs]
- Young GC 日志
- GC 分析工具
- 优化原则
- Full GC 会对整个堆内存进行回收,耗时长,尽量减少 Full GC 次数
- GC tuning is the last task to be done