本篇我们将介绍JVM常用的一些工具,这些工具将是我们监控JVM状态、处理故障和调优分析的利器。 不过在开始之前,我还是要先车扯两句:工具终归只是帮助我们我们处理问题的,想要快速准确的解决问题,最为关键的还是对内在理论的理解和丰富的实践经验,所以如果对JVM的内存处理机制不了解,还是要用心学习一下。好了, 子曰:“工欲善其事,必先利其器。“,下边开始介绍。
一、JDK命令行工具
所有的java开发人员都知道JDK的bin目录下存放着编译java需要的javac,以及运行java程序需要的java这两个命令工具,但是很多人并没有注意到,其实除了这两个工具,该目录下还有很多工具,这些工具其实为我们提供了很多方便且强大的功能,以下是部分截图(各工具作用见:jdk/jre bin下工具介绍):
本篇我们只关注监控和故障处理相关的工具,见下表:
名称 | 作用 |
jps | JVM Process Status Tool,现实指定系统内所有的HotSpot虚拟机进程 |
jstats | JVM Statistics Monitoring Tool,用于收集Hotspot虚拟机各个方面的运行参数 |
jinfo | Configuration Info for Java,现实虚拟机配置信息 |
jmap | Memory map for java,生成虚拟机的内存转储快照 |
jhat | JVM heap Dunp Browser,用于分析heapdump文件,他会建立一个HTTP/HTML服务,让用户可通过浏览器查看 |
jstack | Stack Track for java ,显示虚拟机线程快照 |
下边我们来看一下每个的简单用法:
1、jps
其实应该说这个命令多数人还是比较熟悉的,一般我们想要防止程序启动两次,或者判断某java进程是否存活,都会采用该命令获取系统当前运行的所有java进程,然后根据进程名判断。当然也可以以此获得对应进程的id(此id指JVM里的LVMID,但是他和系统进程ID是一致的),然后kill他来结束程序。其用法如下:
1
2
3
4
5
6
7
8
|
语法结构:
jsp [options] [hostid]
参数:
-q 只输出ID
-l 显示虚拟机执行的主类
-m 显示传给main的参数
-
v
输出启动的JVM参数
|
2、jstat
jstat用于监控虚拟机各种运行状态信息,可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI的情况下他是性能分析的首选工具。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
语法结构:
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
参数:
Options — 选项,我们一般使用 -gcutil 查看gc情况
vmid — VM的进程号,即当前运行的java进程号
interval– 间隔时间,单位为秒或者毫秒
count — 打印次数,如果缺省则打印无数次 S0 — Heap上的 Survivor space 0 区已使用空间的百分比
列说明:
S1 — Heap上的 Survivor space 1 区已使用空间的百分比
E — Heap上的 Eden space 区已使用空间的百分比
O — Heap上的 Old space 区已使用空间的百分比
P — Perm space 区已使用空间的百分比
YGC — 从应用程序启动到采样时发生 Young GC 的次数
YGCT– 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC — 从应用程序启动到采样时发生 Full GC 的次数
FGCT– 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT — 从应用程序启动到采样时用于垃圾回收的总时间(单位秒)
|
3、jinfo
这个命令可以实时查看调整JVM的运行参数,需要注意的是该工具仅在linux下比较有用,win下虽有提供,但是限制很大 ,使用方法如下:
1
2
3
4
5
6
7
|
语法结构:
jinfo [options] pid
参数:
-
v
查看虚拟机显式参数
-flag[+
/-
] 查看所有参数,+
/-
可以添加/减少运行时参数
-sysprops 打印System.getProperties()的内容
|
4、jmap
jmap用于生成堆转储快照(heapdump,用于JVM内存状态分析,是故障处理或调优的关键参考数据),还可以查询finalize队列,java堆和永久代详细信息。此外,该工具同样在win下是个残废。
1
2
3
4
5
6
7
8
9
10
11
12
|
语法结构:
jmap [ option ] pid
参数:
-dump:[live,]
format
=b,
file
=<filename> 使用hprof二进制形式,输出jvm的heap内容到文件=. live子选项是可选的,假如指定live选项,那么只输出活的对象到文件.
-finalizerinfo 打印正等候回收的对象的信息.
-heap 打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
-histo[:live] 打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量.
-permstat 打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来.
-F 强迫.在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效.
-h | -help 打印辅助信息
-J 传递参数给jmap启动的jvm.
|
5、jhat
通常与jmap搭配使用,用来分析jmap生成的heapdump文件,其内置了一个简单的HTTP服务器(哈哈,最近自己也在写一个web服务器,发现其实大体原理挺简单的,麻烦的在于对web应用接口、内部处理细节的设计,以及并发处理,目前已经实现一个简版,有兴趣的见:easy-httpserver ),可以在浏览器中查看分析结果。实际上该工具用处不大,一方面其功能简单,比起常用的VisualVM等工具有一定差距,另一方面在生产环境中去进行比较耗资源的分析处理,估计对不少公司都是犯忌讳的事吧,一般都是把heapdump导到本地处理。
这里就不介绍用法了,可自行谷歌里百度。
6、jstack
看名字就知道是和栈相关的,而栈里边存的则是各个线程的私有数据(局部变量表、方法出口、操作数栈、对象引用等),因此该命令就是用来生成当前虚拟机的线程快照的(threaddump,可用来分析虚拟机某线程长时间挺对的原因,如死锁、死循环、资源请求时间过长等)。
1
2
3
4
5
6
7
8
|
语法结构:
jstack [ option ] pid
参数:
-F当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m打印java和native c
/c
++框架的所有栈信息.
-h | -help打印帮助信息
|
二、JDK可视化工具
这一部分主要有两个工具:JConsole和VisualVM,这两个都提供了很强大的功能,这次先不介绍了。