除了集成式的VisualVM和JConsole外,JDK本身还提供了如jps、jstack、jmap、jhat、jstat等性能调优监控工具。
在Java开发中,有时候我们会碰到下面这些问题:
OutOfMemoryError,内存不足
内存泄露
线程死锁
锁争用(Lock Contention)
Java进程消耗CPU过高
……
这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。本文参考了网上很多资料,对一些常用的JVM性能调优监控工具进行介绍。
1.jps: 主要用来输出JVM中运行的进程状态信息。语法格式如下:
jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
-q 不输出类名、Jar名和传入main方法的参数 -m 输出传入main方法的参数 -l 输出main类或Jar的全限名 -v 输出传入JVM的参数
比如下面:
2.jstat:JVM统计监测工具,可以用于观察Java应用程序运行时信息的工具,它的功能非常强大,可以通过它查看堆信息的详细情况。语法格式如下:
jstat [generalOption | outputOptions vmid [interval[s|ms] [count]]]
命令行参数选项说明如下:
-class 显示加载class的数量及所占空间等信息。 -compiler 显示VM实时编译的数量等信息 -gc 可以显示gc的信息,查看gc的次数,及时间 -gccapacity 可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小 -gccause 最近一次GC统计和原因 -gcnew 年轻代对象的信息 -gcnewcapacity 年轻代对象的信息及其占用量 -gcold old代对象的信息 -gcoldcapacity old代对象的信息及其占用量 -gcpermcapacity perm对象的信息及其占用量 -gcutil 统计gc信息 -printcompilation HotSpot 当前VM执行的信息
示例如下:
3.jinfo:可以用来查看正在运行的Java应用程序的扩展参数,甚至在运行时修改部分参数,它的基本语法为:
jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server-id@]remote-hostname-or-IP
命令行参数选项说明如下:
no option 打印命令行参数和系统属性
-flags 打印命令行参数 -sysprops 打印系统属性
示例如下:
4.jmap:主要用于生成堆快照文件,语法格式如下:
jmap [option] pid
jmap [option] executable core
jmap [option] [server-id@]remote-hostname-or-ip
命令行行参数选项说明如下:
-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子参数无效. -J 传递参数给jmap启动的jvm.
示例如下:
获得堆快照文件之后,我们可以使用多种工具对文件进行分析,例如jhat,VisualVM等。
5.jhat:可以分析Java应用程序的堆快照文件,语法格式如下:
jhat在分析完成之后,使用HTTP服务器展示其分析结果,在浏览器中访问http://127.0.0.1:7000/即可得到分析结果。
6.jstack:主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
jstack [option] pid
jstack [option] executable core
jstack [option] [server-id@]remote-hostname-or-ip
命令行参数选项说明如下:
-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况 -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
把堆栈信息打印到文件中,从文件中可以看出是否有死锁的情况。