目录
- 一、JDK工具1、JDK工具2、利用 jps 找出进程3、利用 jstat 查看VM统计信息4、利用 jmap 查看对象分布情况5、利用 jstack 分析线程栈
- 二、Linux 命令行工具1、top 命令2、vmstat 命令3、pidstat 命令
- 三、可视化工具1、jvisualvm — JVM监控3、GCViewer — 离线分析GC日志4、GCeasy — 在线分析GC日志5、FastThread — 分析线程栈6、MAT — 分析堆转储文件7、性能调优工具8、JVM监控平台
- 四、利用工具分析JVM运行情况1、运行示例程序2、新生代对象增长的速率3、YoungGC的触发频率和耗时4、YoungGC后存活对象大小以及有多少对象进入了老年代5、FullGC的触发频率和耗时6、使用GCeasy查看GC日志7、性能优化
- 五、使用 MAT 分析OOM问题1、运行示例程序2、MAT 分析OOM问题的思路3、总览图 — 快速分析OOM问题4、直方图 — 定位根源5、支配树 — 定位根源6、线程栈 — 分析代码7、OQL—查询数据
- 六、使用 Arthas 分析高 CPU 问题1、运行示例程序2、启动 Arthas3、dashboard — 展示整体情况4、thread — 查看高CPU的线程5、watch — 监控参数6、jad — 反编译7、redefine — 重载类
- 参考
前序文章:
JVM性能调优(1) —— JVM内存模型和类加载运行机制
JVM性能调优(2) —— 垃圾回收器和回收策略
JVM性能调优(3) —— 内存分配和垃圾回收调优
回到顶部
一、JDK工具
先来看看有哪些常用的工具可以辅助我们进行性能调优和问题排查,后面再通过一个具体的示例结合工具来分析调优。
1、JDK工具
JDK自带了很多性能监控工具,我们可以用这些工具来监测系统和排查内存性能问题。
2、利用 jps 找出进程
jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。
1)查看Java进程PID
【jps -l】左边一列就是Java进程的PID。
2)输出传递给JVM的参数
【jps -vl】
3、利用 jstat 查看VM统计信息
使用 jstat 工具可以监测 Java 应用程序的实时运行情况,可以看到VM内的Eden、Survivor、老年代的内存使用情况,还有 YoungGC 和 FullGC 的执行次数以及耗时。通过这些指标,我们可以轻松的分析出当前系统的运行情况,判断当前系统的内存使用压力以及GC压力,还有内存分配是否合理。
1)查看 jstat 有哪些操作
【jstat -options】
- -class:显示 ClassLoad 的相关信息;
- -compiler:显示 JIT 编译的相关信息;
- -gc:显示和 gc 相关的堆信息;
- -gccapacity:显示各个代的容量以及使用情况;
- -gcmetacapacity:显示 Metaspace 的大小;
- -gcnew:显示新生代信息;
- -gcnewcapacity:显示新生代大小和使用情况;
- -gcold:显示老年代和永久代的信息;
- -gcoldcapacity :显示老年代的大小;
- -gcutil:显示垃圾收集信息;
- -gccause:显示垃圾回收的相关信息(同 -gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
- -printcompilation:输出 JIT 编译的方法信息
其中 jstat -gc 是最完整、最常用、最实用的命令,基本足够分析jvm的运行情况了。
2)显示 ClassLoad 的相关信息
【jstat -class <pid>】
3)查看内存使用和GC情况
【jstat -gc <pid> [<interval> [<count>]】
- S0C:年轻代中 To Survivor 的容量(单位 KB);
- S1C:年轻代中 From Survivor 的容量(单位 KB);
- S0U:年轻代中 To Survivor 目前已使用空间(单位 KB);
- S1U:年轻代中 From Survivor 目前已使用空间(单位 KB);
- EC:年轻代中 Eden 的容量(单位 KB);
- EU:年轻代中 Eden 目前已使用空间(单位 KB);
- OC:老年代的容量(单位 KB);
- OU:老年代目前已使用空间(单位 KB);
- MC:Metaspace 的容量(单位 KB);
- MU:Metaspace 目前已使用空间(单位 KB);
- CCSC:压缩类空间大小
- CCSU:压缩类空间使用大小
- YGC:从应用程序启动到采样时年轻代中 gc 次数;
- YGCT:从应用程序启动到采样时年轻代中 gc 所用时间 (s);
- FGC:从应用程序启动到采样时 old 代(全 gc)gc 次数;
- FGCT:从应用程序启动到采样时 old 代(全 gc)gc 所用时间 (s);
- GCT:从应用程序启动到采样时 gc 用的总时间 (s)
4)查看垃圾回收统计
【jstat -gcutil <pid> [<interval> [<count>]】
- S0:Survivor0 区占用百分比
- S1:Survivor1 区占用百分比
- E:Eden 区占用百分比
- O:老年代占用百分比
- M:元数据区占用百分比
- YGC:年轻代回收次数
- YGCT:年轻代回收耗时
- FGC:老年代回收次数
- FGCT:老年代回收耗时
- GCT:GC总耗时
4、利用 jmap 查看对象分布情况
使用 jmap 可查看堆内存初始化配置信息以及堆内存的使用情况,输出堆内存中的对象信息,包括产生了哪些对象,对象数量多少等。
1)查看堆内存情况
【jmap -heap <PID>】
这个命令会打印出堆内存相关的一些参数设置以及各个区域的情况,要查看这些信息一般使用 jstat 命令就足够了。
2)查看系统运行时对象分布
【jmap -histo[:live] <PID>】带上 live 则只统计活对象
这个命令会按照各种对象占用内存空间的大小降序排列,把占用内存最多的对象放在最上面。通过这个命令可以简单的了解下当前jvm中的对象对内存占用的情况以及当前内存里到底是哪个对象占用了大量的内存空间。
3)生成堆内存转储快照
【jmap -dump:format=b,file=<path> <pid>】
【jmap -dump:live,format=b,file=<path> <pid>】
jmap -dump 是输出堆中所有对象;jmap -dump:live 是输出堆中所有活着的对象,而且 jmap -dump:live 会触发 FullGC,线上使用要注意。format=b 是以二进制格式输出;file 是文件路径,格式为 hrpof 后缀。
这个命令会在当前目录下生成一个 dump.hrpof 文件,这是个二进制的格式,无法直接打开,可以使用MAT等工具来分析。这个命令把这一时刻VM堆内存里所有对象的快照放到文件里去了,供你后续去分析。
5、利用 jstack 分析线程栈
jstack 是一种线程堆栈分析工具,最常用的功能就是使用 jstack pid 命令查看线程的堆栈信息,通常会结合 top -Hp pid 或 pidstat -p pid -t 一起查看具体线程的状态,也经常用来排查一些死锁的异常、CPU占用高的线程等。
1)jstack参数
- -l:长列表. 打印关于锁的附加信息,例如属于 java.util.concurrent 的 ownable synchronizers 列表。
- -F:当 jstack [-l] pid 没有响应的时候强制打印栈信息
- -m:打印 java 和 native c/c++ 框架的所有栈信息.
- -h | -help:打印帮助信息
2)查看线程堆栈信息
【jstack <pid> > stack.log】
这个命令可以把程序的线程堆栈dump下来。每个线程堆栈的信息中,都可以查看到线程