Java内存泄露监控工具:JVM监控工具介绍
本文将对JVM监控工具jstack, jconsole, jinfo, jmap, jdb, jstat进行详细的介绍,具体内容请看下文
名称
|
主要作用
|
jps
|
JVM Process Status Tool,显示指定系统内所有的HotSpot虚拟进程
|
jstat |
JVM Statistcs Monitoring Tool,用于手机HotSpot虚拟机各方面的运行数据
|
jinfo
|
Configuration Info for java,实时查看和调整虚拟机各项参数信息
|
jmap
|
Memory Map for Java,生成转储快照(一般称为headdump或dump文件)
|
jhat
|
JVM Heap Analysis Tool,与jmap搭配使用,分析jmap生成的转储快照
|
jstack
|
Stack Trace for Java,生成虚拟机当前时刻的线程快照(一般称为threddump或javacore文件)
|
1.jps:虚拟机进程状况工具
可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class, main()函数所在的类)的名称,以及这些进程的本地虚拟机的唯一ID。
jps可以通过RMI协议查询开启了RMI服务的远程虚拟机进程状态,hostid为RMI注册表中注册的主机名。默认端口为1099。(前提是远程服务器提供jstatd服务)
jps命令格式:
jps [-q] [-mlvV] [<hostid>]
options :
-q 只输出LVMID,省略主类的名称
-m 输出虚拟机京城启动时传递给主类main()函数的参数
-l 输出主类的全名,如果京城执行的是Jar包,输出Jar路径
-v 输出虚拟机进程启动时JVM参数
jps -l
2.jstat:虚拟机统计信息监视工具
用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
jstat命令行格式为:
jstat [ options vmid [interval [s|ms] [count ] ] ] jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]] 对于命令格式中的VMID与LVMID需要特别说明一下:如果是本地虚拟机进程,VMID与LVMID是一致的,如果是远程虚拟机进程,那VMID的格式应当是:
[protocl:] [//]lvmid[@hostname[:port]/servername]
参数interval和count代表查询间隔和次数,如果省略这两个参数,说明只查询一次。架设需要每50ms查询一次进程1366垃圾收集的状况,一共查询2次,那命令应当是:
jstat -gc 1366 50 2
选项option代表这用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集、和运行期编译状况,具体选项及作用请参考描述。
options:
-class 监视类装载、卸载数量、总空间及类装载耗费的时间
-gc 监视java堆状况,包括Eden区、2个survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息
-gccapacity 监视内容与-gc基本相同,但输出主要关注java堆各个区域使用到的最大和最小空间
-gcutil 监视内容与-gc基本内容,但输出主要关注已使用空间占总空间的百分比
-gccause 与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew 监视新生代GC的状况
-gcnewcapacity 监视内容与-gcnew 基本相同,输出主要关注使用到的最大和最小空间
-gcold 监视老年代GC的状况
-gcoldcapacity 监视内容与-gcold基本相同,输出主要关注使用到的最大和最小空间
-gcpermcapaciyt 输出永久带使用到的最大和最小空间
-complier 输出JIT编译器编译过的方法、耗时等信息
-printcompilation 输出已被JIT编译的方法
jstat监视选项忒多,囿于篇幅限制无法一一详述。仅此浅析-gcutil结果。
jstat -gcutil 1366
E,表示Eden,新生代Eden区使用了21.53%的空间
S0、S1,表示两个Survivor区Survivor0、Survivor1里S0使用了74.81%的空间,S1为空的
O,表示Old,老年代使用了82.78%
P,表示Permanent,永生代使用了85.78%
YGC,表示Young GC次数,新生代做了42次垃圾收集
YGCT,表示Young GC总耗时,新生代垃圾收集总耗时为0.970秒
FGC,表示Full GC次数,全内存域做了4次垃圾收集
FGCT,表示Full GC总耗时,全内存域垃圾收集总耗时为2.113秒
GCT,表示所有GC总耗时,所有内存域垃圾收集总耗时为3.083秒
使用jstat工具在纯文本状态下监视虚拟机状态的变化,确实不如VisualVM、Jprofile等可视化监视工具以图表展现形式直观,但jstat以其较小的资源占用率博得众多服务器管理员、性能测试人员的青睐。
3、jinfo:java配置信息工具
用于实时查看和调整虚拟机各项参数。使用jps命令的-v参数可以查看虚拟机启动时显示指定的参数列表,但如果想知道未被显式指定的参数,就只能利用jinfo的-flag选项进行查询了。
当然JDK1.6或以上版本的话,使用java -XX:+PrintFlagsFinal查看参数默认值也是极好的。
jinfo命令格式:
jinfo [option] <pid>
where <option> is one of:
-flag <name> to print the value of the named VM flag
-flag [+|-]<name> to enable or disable the named VM flag
-flag <name>=<value> to set the named VM flag to the given value
下面我们来展示下查询CMSInitiatingOccupancyFraction参数:
jinfo -flag CMSInitiatingOccupancyFraction 1366
4、jmap:java内存快照工具
用于生成堆转储快照。
如果不适用jmap命令,想要获取Java堆转储快照还有一些比较“暴力”的手段,譬如:
-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在OOM异常出现之后自动生成dump文件
-XX:+HeapDumpOnCtrlBreak参数则可使用[Ctrl]+[Break]键让虚拟机生成dump文件
当然如果在linux系统下通过kill -3命令发送进程退出信号“恐吓”一下虚拟机,也能拿到dump文件
jmap的作用并不仅仅是为了获取dump文件,它还可以查询finalize执行队列,java堆和永久代的详细信息,如空间使用率、当前用的是哪种GC收集器等。
jmap命令格式:
jmap [option] <pid>
options:
-dump 生成java堆转储快照
-finalizerinfo 显示在F-Queue中等待Finalizer线程执行finalize方法的对象
-heap 显示java堆详细信息,如使用哪种回收器、参数配置、分代状况等
-histo 显示堆中对象统计信息,包括类、实例数量和合计容量
-permstat 以ClassLoader为统计口径显示永久代内存状态
-F 当虚拟机进程对-dump选项没有响应时,可使用这个选项生成dump快照
5、jhat:虚拟机堆转储快照分析工具
与jmap搭配使用,分析jmap生成的堆转储快照。jhat内置了一个微型http/html服务器,生成dump文件的分析结果,可以在浏览器中查看。
jhat的功能并不是很强大,并且在服务器上直接分析dump文件过分的消耗了硬件资源。在此推荐利用VisualVM、Eclipse Memory Analyzer、IBM HeapAnalyzer等工具。
jhat 命令格式:
jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file>
6、jstack:java堆栈跟踪工具
用于生成虚拟机当前时刻的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈计划。
生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做些什么事情,或者等待着什么资源。
jstack命令格式:
jstack [option]<pid>
options:
-F 当正常输出的请求不被响应时,强制输出线程堆栈
-l 打印除堆栈以外关于锁的附加信息
-m 如果调用到本地方法的话,可以显示C/C++的堆栈
浮生潦草闲愁广,一听啤酒一口尽