JVM性能监控及故障处理工具

jopen 10年前

    本篇我们将介绍JVM常用的一些工具,这些工具将是我们监控JVM状态、处理故障和调优分析的利器。 不过在开始之前,我还是要先车扯两句:工具终归只是帮助我们我们处理问题的,想要快速准确的解决问题,最为关键的还是对内在理论的理解和丰富的实践经验,所以如果对JVM的内存处理机制不了解,还是要用心学习一下。好了, 子曰:“工欲善其事,必先利其器。“,下边开始介绍。

一、JDK命令行工具

    所有的java开发人员都知道JDK的bin目录下存放着编译java需要的javac,以及运行java程序需要的java这两个命令工具,但是很多人并没有注意到,其实除了这两个工具,该目录下还有很多工具,这些工具其实为我们提供了很多方便且强大的功能,以下是部分截图(各工具作用见:jdk/jre bin下工具介绍):

    JVM性能监控及故障处理工具

    本篇我们只关注监控和故障处理相关的工具,见下表:

名称     作用
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他来结束程序。其用法如下:

语法结构:  jsp [options] [hostid]    参数:  -q 只输出ID  -l 显示虚拟机执行的主类  -m 显示传给main的参数  -v 输出启动的JVM参数

2、jstat

    jstat用于监控虚拟机各种运行状态信息,可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI的情况下他是性能分析的首选工具。

语法结构:  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下虽有提供,但是限制很大 ,使用方法如下:

语法结构:  jinfo [options] pid    参数:  -v 查看虚拟机显式参数  -flag[+/-] 查看所有参数,+/-可以添加/减少运行时参数  -sysprops 打印System.getProperties()的内容

4、jmap

    jmap用于生成堆转储快照(heapdump,用于JVM内存状态分析,是故障处理或调优的关键参考数据),还可以查询finalize队列,java堆和永久代详细信息。此外,该工具同样在win下是个残废。

语法结构:  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,可用来分析虚拟机某线程长时间挺对的原因,如死锁、死循环、资源请求时间过长等)。  

语法结构:  jstack [ option ] pid    参数:  -F当’jstack [-l] pid’没有相应的时候强制打印栈信息  -l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.  -m打印java和native c/c++框架的所有栈信息.  -h | -help打印帮助信息

二、JDK可视化工具

    这一部分主要有两个工具:JConsole和VisualVM,这两个都提供了很强大的功能,这次先不介绍了。