1.工欲善其事:JDK提供的工具
- Java试题
JVM调优的常见命令行工具描述正确的有:
A.jstat可以实时显示本地或远程JVM进程中类加载、内存、垃圾收集、JIT编译等数据
B.jmap用于查询当前运行的JVM属性和参数的值
C.jstack用于生成当前JVM的所有线程快照
D.jps命令用于查询正在运行的JVM进程
- 试题解读
这道题考察JDK自带命令行工具的理解,这些工具用于性能调优、疑难问题定位。
在生产环境定位时,要求定位/调优工具自身具备极高的性能,否则会对本来就有问题的生产环境产生干扰。
JDK自带的命令行工具以其的高性能、实用性,成为实战中必须掌握的工具,是Java程序猿的调优武器库。
2.总览
2.1.主流工具概览
目前,主流的Java性能监控与调优工具如下图所示:
这些工具主要分为两个流派:“命令行流派
"与"可视化流派
”
- **命令行流派:**强调实用性。体积小、资源消耗小,适用于生产环境的问题定位与调优。
- **可视化流派:**强调颜值即正义。可视化图表、一目了然,适用于开发环境上复现、定位问题。
这两种流派各有适用的场景,辩证统一,所以还是那句话:“成年人不做选择,两样我都要”。
|
|
2.2.理解命令行工具的内在逻辑
对于这些命令行工具,有一种观点:没有必要记下来,用到的时候再查资料
。
因为这些命令行工具比较多,每个命令行也有很多参数,记下来是一件枯燥的事。
但,这个观点成立有一个前提:我们必须理解这些命令行工具的内在逻辑
:
- **逻辑1:**这些命令行工具的关系是什么?
- **逻辑2:**每个工具解决什么问题?
- **逻辑3:**每个工具的参数集合分哪几类?
如果没有理解上述内在逻辑
,需要用的时候再查资料也很难入手。
对于逻辑1:这些命令行工具的关系
,笔者提供一种基于实战问题定位的场景
的理解方式:
- **STEP1.进程监控:**首先,找到生产环境中待定位的Java进程。
- **STEP2.配置查询:**进一步,查看此Java进程的JVM配置。
- **STEP3.JVM状态监控与初步分析:**再进一步,查看此Java进程的内存、线程、JIT的整体情况。
- STEP4.内存监控与分析:如果STEP3发现了可能的内存问题,就深入分析内存。
- **STEP5.线程监控与分析:**如果STEP3发现了可能的线程问题,就深入分析线程。
2.3.进阶的方法
- **命令行手册:**我们可以通过官方的命令行手册,深入学习它们。
- **工具源码:**通过这些命令行工具的源码,可以更深入地理解JVM状态监控的原理和API。
|
|
3.进程监控-jps
3.1.解决什么问题
jps用来显示指定系统内所有正在运行的HotSpot虚拟机进程信息。
3.2.参数
- jps的参数格式如下:
|
|
我们可以通过几个实际的例子,快速理解[options]
**例子:**
jps
**例子:**
jps -q
**例子:**
jps -lmv
我们可以发现,无论怎样的options,一定会显示JVM identifiers
,不同的options只是在JVM identifiers
的基础上显示更多的额外信息。
了解到这个程度,实战中如有需要,可以再进一步查看命令行手册:
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jps.html#CHDCGECD
4.配置查询-jinfo
4.1.解决什么问题
jinfo用来查看JVM虚拟机参数,同时可以修改部分JVM虚拟机参数。
4.2.参数
- jinfo的参数格式如下:
|
|
我们可以通过几个实际的例子,快速理解[options]
- **例子:**
jinfo <pid>
——查看此JVM进程所有的配置
- **例子:**
jinfo -sysprops <pid>
——等价于查看System.getProperties()
- **例子:**
jinfo -flags <pid>
——查看所有参数
- **例子:**
jinfo -flags <参数名> <pid>
——查看某个参数的值
我们可以发现:
- JVM进程的配置分为两类:
系统环境变量
和JVM参数
,jinfo的参数用来输出上述两类配置。 - jinfo支持输出所有的配置值,也可以输出某一个指定参数的值。
了解到这个程度,实战中如有需要,可以再进一步查看命令行手册:
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jinfo.html#BCGEBFDD
5.JVM状态监控与初步分析-jstat
5.1.解决什么问题
jstat可以输出JVM的各类状态(类加载、内存、GC、JIT)。
初步定位的时候,就是通过上述状态,找到诸如内存泄露、线程死锁等问题的蛛丝马迹。
5.2.参数
- jstat的参数格式如下:
|
|
- **例子:**jstat -class -t -h3
1000 5——采集类加载信息(每1000ms采样一次,采集5次,每3行打印1次表头)。
- **例子:**jstat -compiler -t -h3
1000 5——采集JIT信息(每1000ms采样一次,采集5次,每3行打印1次表头)。
- **例子:**jstat -printcompilation -t -h3
1000 5——采集已经被JIT编译过的方法(每1000ms采样一次,采集5次,每3行打印1次表头)。
**例子:**jstat -gc -t -h3
1000 5——采集GC的情况(每1000ms采样一次,采集5次,每3行打印1次表头)。 **例子:**jstat -gccapacity -t -h3
1000 5 **例子:**jstat -gcutil -t -h3
1000 5 **例子:**jstat -gccause -t -h3
1000 5
我们可以发现:
- 采样相关的参数:-t(Timestamp列,单位s) 、-h(周期性的增加表头)、interval(采样周期,单位ms)、count(采集次数)
- 类加载相关的参数:-class,显示ClassLoader信息,如:类加载数量、类卸载数量、总空间、类装载消耗的时间。
- JIT相关的参数:-compiler(显示JIT编译过的方法、耗时)、-printcompilation(输出已经被JIT编译的方法)
- **垃圾回收相关的参数:**gcXxx,例如:-gc:显示GC相关的堆信息。包括Eden、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息。
在此展开看一下垃圾回收相关参数输出的Gc信息,我们可以发现无论哪个gcXxx参数,都会输出如下信息:
- 新生代相关
|
|
- 老年代相关
|
|
- 方法区相关
|
|
- GC相关——如果发现两行之间的GC时间占总时间过长或者内存占用不断增加,说明可能有内存问题。
|
|
了解到这个程度,实战中如有需要,可以再进一步查看命令行手册:
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jstat.html#BEHHGFAE
6.内存监控与分析-jmap/jhat
6.1.解决什么问题
- jmap可以将内存信息导出为dump文件(也叫做堆转储快照文件)。
- 当用jstat初步定位发现疑似内存泄露时,就可以通过jmap将内存快照导出出来,进一步定位。
- jhat可以导入jmap导出的内存快照文件,进行相对可视化的查看。
- jhat内置了一个微型的http服务器,用于查看dump文件的分析结果。
- JDK11已经删除了jhat,官方推荐用VisualVM替代。
6.2.参数
- jmap的参数格式如下:
|
|
- **例子:**jmap -dump:format=b,file=<filepath.hprof>
——手动导出某个时间点的内存快照,会触发1次FullGC,dump文件中会保存FullGC后留下的对象信息,对于大内存镜像会比较耗时。 - **例子:**java -jar xxx.jar -Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<filepath.hprof>——当待定位的系统发生OOM的时候出现闪退时,此时会自动导出dump文件。
当然,如何分析dump文件是一个更大的话题,后续再展开。仅针对jmap命令行了解到这个程度,实战中如有需要,可以再进一步查看命令行手册:
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jmap.html#CEGCECJB
7.线程监控与分析-jstack
7.1.解决什么问题
jstack可以生成虚拟机指定进程当前时刻的线程快照,用于定位线程长时间停顿的原因。
7.2.参数
- jstack的参数格式如下:
|
|
- **例子:**jstack
——如果程序中有线程死锁,会在dump文件中体现出来。
了解到这个程度,实战中如有需要,可以再进一步查看命令行手册:
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/jstack.html#BABGJDIF
8.总结
本文主要内容:
- JVM性能监控与调优的工具有两种流派:命令行工具、可视化工具。
- 学习命令行工具集的内在逻辑:工具间的关系、每个工具解决的问题、每个工具的参数分类。
- 进程监控工具:jps
- 配置查询工具:jinfo
- JVM状态监控工具:jstat
- 内存监控与分析工具:jmap、jhat(jdk11用VisualVM替代)
- 线程监控与分析工具:jstack
9.参考文献
https://docs.oracle.com/javase/8/docs/technotes/tools/windows/