深入理解Java虚拟机笔记三(JVM性能监控与故障处理工具)

Contents

  1. 1. 概述
  2. 2. JDK的命令行工具
    1. 2.1. jps:虚拟机进程状况工具
    2. 2.2. jstat:虚拟机统计信息监视工具
    3. 2.3. jinfo:Java配置信息工具
    4. 2.4. jmap:Java内存映像工具
    5. 2.5. jhat:虚拟机堆转储快照分析工具
    6. 2.6. jstack:Java堆栈跟踪工具
    7. 2.7. JDK的可视化工具

概述

大多工具都是对jdk/lib/tools.jar类库的一层包装,SUN JDK监控和故障处理工具:

  1. jps:JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程
  2. jstat:JVM Statistics Monitoring Tool,用于收集HotSpot虚拟机各方面的运行数据
  3. jinfo:Configuration Info for Java,显示虚拟机配置信息
  4. jmap:Memory Map for Java,生成虚拟机的内存转储快照(heap dump文件)
  5. jhat:JVM Heap Dump Browser,用于分析heap dump文件,会建立一个HTTP/HTML服务器,让用户可以在浏览器查看分析结果
  6. jstack:Stack Trace for Java,显示虚拟机的线程快照

然后还有两个GUI工具:

  1. jconsole:略微过时的JVM各状态查看工具
  2. visualVM:Sun出品的强大的JVM工具,推荐使用!

JDK的命令行工具

jps:虚拟机进程状况工具

它和Unix的ps命令有类似功能:

它可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Claas,main()函数所在的类)的名称,以及这些进程的内地虚拟机的唯一ID(LVMID,Local Virtual Machine Identifier)。

命令格式:

1
jps [options] [hostid]
选项 作用
-q 只输出LVMID,省略主类的名称
-m 输出虚拟机进程启动时传递给主类main()函数的参数
-l 输出主类的全名,如果进程执行的是jar包,输出jar包路径
-v 输出虚拟机进程启动时JVM参数

jstat:虚拟机统计信息监视工具

jstat的全称是JVM Statistics Monitoring Tool,它用于监视虚拟机各种运行状态信息。可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只提供纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。

命令格式:

1
jstat [options vmid [interval[s|ms] [count]] ]

假如我想监控gc,每250ms查询一次,一共查询20次,进程号为1234。命令就是:jstat -gc 1234 250 20。如何监控远程机器呢?很简单,使用jstatd。和mysql类似,mysql是客户端,mysqld是服务器端。所以当远程机器开始了jstatd,就相当于开启了远程虚拟机进程的监控,本地可通过RMI查看远程机器的运行时数据,非常方便。

在这里,option主要分为3类:

  1. 类装载
  2. 垃圾收集
  3. 运行期编译状况
选项 作用
-class 监视类装载、卸载数量、总空间及类装载所耗费的时间
-gc 监视Java堆状况,包括Eden区、2个survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息
-gccapacity 监视内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大和最新空间
-gcutil 监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause 监视内容与-gc基本相同,但会额外输出导致上一次GC产生的原因
-gcnew 监视新生代GC状况
-gcnewcapacity 监视内容与-gcnew基本相同,输出主要关注使用到的最大和最小空间
-gcold 监视老年代GC的状况
-gcoldcapacity 监视内容与-gcold基本相同,输出主要关注使用到的最大和最小空间
-gcpermcapacity 输出永久代使用到的最大和最小空间
-compiler 输出JIT编译期编译过的方法、耗时等信息
-printcomplilation 输出已经被JIT编译的方法

jinfo:Java配置信息工具

jinfo全称为Configuration Info for Java,它的作用是实时地查看和调整虚拟机的各项参数

命令格式:

1
jinfo [ option ] pid

使用jps命令的-v参数可以查看虚拟机启动时显式指定的参数列表,但如果想知道未被显式指定的参数的系统默认值,除了去找资料外,就只能使用jinfo的-flag选项进行查询了(如果只限于JDK1.6或以上版本的话,使用java -XX:+PrintFlasFinal查看参数默认值也是一个很好的选择),jinfo还可以使用-sysprops选项把虚拟机进程的System.getProperties()的内容打印出来。可以使用-flag [+-] name或-flag name=value修改一部分运行期可写的虚拟机参数值。

jmap:Java内存映像工具

jmap全称为Memory Map for Java,它用于生成堆转储快照(一般称为heap dump或者dump文件)。jmap的作用并不仅仅是为了获取dump文件供其他工具分析当前JVM的内存情况,它还可以查询finalize执行队列,Java堆和永久代的详细信息,如空间使用率、当前用的是哪种收集器等。它的命令格式为:

1
jmap [ option ] vmid
选项 作用
-dump 生成java堆转储快照。格式为:-dump:[live,]format=b,file=,其中live子参数说明是否只dump出存活的对象
-finalizerinfo 显示在F-Queue中等待Filalizer线程执行finalize方法的对象,只在Linux/Solaris平台下有效
-heap 显示java堆详细信息,如使用哪种回收器、参数配置、分代状况等,只在Linux/Solaris平台下有效
-histo 显示堆中统计信息,包括类、实例数量和合计容量
-permstat 以ClassLoader为统计口径显示永久代内存状态。只在Linux/Solaris平台下有效
-F 当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照。只在Linux/Solaris平台下有效

比如我得到dump快照,就可以先通过jps拿到虚拟机的LVMID,然后使用jmap -dump:format=b,file=haha.bin <LVMID>就可以了。

jhat:虚拟机堆转储快照分析工具

jhat命令与jmap搭配使用,来分析jmap生成的堆转储快照。jhat内置了一个微型的http/html服务器,生成dump文件的分析结果后,可以在浏览器中查看。但一般情况下,这个命令使用的几率不会太大。首先对于线上服务器来说,生成dump快照后,分析快照是一个很耗时且吃硬件的过程,如果dump快照过于复杂,甚至会影响线上服务;其次jhat的分析功能相对来说比较简陋。建议是将这个dump快照拷贝到线下,然后使用更强大的GUI工具来直观分析,比如Eclipse Memory Analyzer、IBM HeapAnalyzer等工具。

如果打开后,可以在本地localhost:7000查看结果。拉到最下面有个Heap Histogram,点进去就可以看到虚拟机中所有对象实例的数目和大小。

jstack:Java堆栈跟踪工具

jstack全称为Stack Trace for Java,它用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机内存每一个线程正在执行的方法堆栈的集合。生成线程快照的主要目的就是定位线程出现长时间停顿的原因,比如线程间死锁、死循环、请求外部资源导致的长时间等待都是导致线程长时间停顿的常见原因。

命令格式:

1
jstack [ option ] vmid

option选项说明如下:

选项 作用
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-l 除堆栈外,显示关于锁的附加信息
-m 如果调用到本地方法的话,可以显示C/C++的堆栈

在JDK 1.5中,java.lang.Thread类新增了一个叫做getAllStackTraces()方法用于获取虚拟机中所有线程的StackTraceElement对象,使用这个方法可以通过简单的几行代码就完成jstack的大部分功能。

JDK的可视化工具

JDK除了提供大量的命令行工具外,还提供了两个功能强大的可视化工具:JConsole和VisualVM,这两个工具是JDK的正式成员

其实现在Sun主推VisualVM了,因为JConsole稍微有点老。而且可视化工具基本不需要学习,稍微看看就知道啥情况。说白了就是把上面的jdk工具,比如jstat、jmap、jstack结果套个GUI。

其中看了感觉比较有价值的是BTrace这个插件,它竟然可以动态的在项目中插入调试信息

Updated: