JDK内置帮助JVM故障定位与处理的几个小工具的简单使用

前言

    JVM进行故障定位主要是对系统运行时的一些数据进行处理及分析,如堆栈信息、线程快照等。JDK自带了一些工具可以帮助开发人员或才运维人员进行故障定位。当然了在开发过程中可能用到的相对较少,一般是在线上环境时进行故障定位或才优化时需要相关数据分析。

    这些工具包括虚拟机进程状况工具(jps)、虚拟机统计信息监视工具(jstat)、java配置信息工具(jinfo)、java内存映像工具(jmap)、虚拟机堆转储快照分析工具(jhat)、java堆栈跟踪工具(jstack)和可视化的多合一故障处理工具(jvisualvm)

ps:这些工具在安装 JDK的时候都在JDK的bin目录下,就和java、javac一样,如果配置了环境变量直接调用jps、jvisualvm我等命令就可以看到,当然了在一些线上环境权限设置比较严格的或者没有配置环境变量的,可以直接进行bin目录内执行。另外,本文基于JDK1.7测试的。

接下对这些工具的简单使用及一些场景进行下说明,本文只列出个人常用的一些用法及参数说明,详细的了解推荐阅读《深入理解Java虚拟-JVM高级特性与最佳实践》一书的第4章:虚拟机性能监控与故障处理工具:

1. jps:虚拟机进程状况工具

    简单来说,它的作用和ps命令一样,但是只显示java进程。

    执行jps就会把当前系统的所有java进程列表出来,左侧一列是进程号,右侧是虚拟机执行主类名。不过建议使用jps -l,输出主类全名或执行jar包的路径,这样可以更容易区分是哪个进程。

    其它还有-v(输出虚拟机启动时JVM参数),-m(启动时传递给主类的参数)等。

    我个人其实使用的jps -l比较多,就是查看下进程信息。

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

    这个主要是对虚拟机运行状态监控的工具,笔者平常就用它查下GC信息。

    命令基本用法:jstat 参数 进程ID 查询间隔 查询次数,如jstat -gc 11036 1000 5,就是查询进程11306的java堆的GC状况,每隔1秒(1000ms)查询一次,共查询5次,具体效果如下图:

JDK内置帮助JVM故障定位与处理的几个小工具的简单使用

    我首先用jps -l查询了本机运行的java进程信息,然后查看了11036进程的GC信息,对于GC信息的各个字段说明如下:

S0C/S1C:这是两个Survivor(Survivor0和Survivor1区的总内存,这两个区属性新生代的一部分)

S0U/S1U:就是两个Survivor的已经使用内存

EC:就是新生代Eden区的总内存,EU:则是新生代Eden区的已使用内存(C/U这两个简写需要望文生义)

OC:老年代总内存,OU:老年代已用内存

PC:持久代总内存,PU:持久代已用内存(JDK1.8其实不用太关注持久代,毕竟移除了,其实这个区实际上可以动态增长了)

YGC:新生代的GC总次数,YGCT:新生代的GC总时间

FGC:整个堆内存进行GC的总次数,FGCT:Full GC花费的总时间

GCT:整个GC过程花费的总时间

3. jinfo:Java配置信息工具 

    这个工具主要用来查看虚拟机参数,和环境变量的值,这里重点提下环境变量的值:

    使用jifno -sysprops 进程ID,即可查看该进程使用System.getProperties()获取到的所有内容。包括运行过程中代码System.setProperty(k,v)等设置的所有的内容。有某些特殊情况定位数据很有用了,用到了就知道了。

ps:其它用法参考下文提到的参考资料查看即可,本文只是对某些内容作一下重点强调和补充

4. jmap:Java内存映像工具

    这个工具用于生成堆转储快照。本方只对基本用法进行举例说明:

    用法:jamp 参数 进程ID,想要堆转储快照参考这个示例(在JDK1.7测试):jmap -dump:format=b,file=test.hprof 11036,会在用户目录下生成一个进程11036的dump快照文件test.hprof,具体怎么分析这个文件,且看下文。

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

    这个工具就是对第4节的文件进行可视分析,使用示例:jhat test.hprof,会在本地启动一个服务器,默认端口7000,可以通过浏览器访问http://localhost:7000/就可以查看了。启动前保证端口7000没有被其它进程占用。

    建议不用这个工具,如果条件允许,请使用下文说明的jvisualvm进行分析。

6. jstack:Java堆栈跟踪工具

    这个工具,可以生成本地线程快照,用法:jstack 参数 进程ID,示例:jstack 11036(参数可选).

    ps:进程如果太多,建议保存到一个文件,用一个功能便捷的文本工具根据自己想要的信息进行统计分析。也可以生成一个快照导入jvisualvm查看

7. jvisualvm:可视化的多合一故障处理工具

    这个用起来就很爽,直观的界面,强大监控功能与数据分析。直接输入jvisualvm命令即可打开,可以监控本地也可以远程连接。至于它可以做哪些希望可以查阅本文最后的参考资料,或者自己打开看一下。

    主要说下用它的比较尴尬的地方:1、线上环境可能是不支持的,一般是堆转储快照或者线程快照拉到下来在线下的机器上打开jvisualvm进行分析;2、堆文件过大的时候,分析起来对机器的配置要求真的非常高,要不分析个数据每点一下都要等好久,才能出来结果;3、掌握OQL脚本语言会定位起来更轻松一点,增加了使用成本。反正之前笔者公司有个同事后两条条件都具备,10个G的dump被人家用来分析真是6的不要不要的。

    所以这个工具的使用就看个人的道行深浅了。如果是基本的看内存、CPU信息什么的,就没什么要求了。

参考资料

《深入理解Java虚拟-JVM高级特性与最佳实践》