本文介绍JVM的常用工具。
jps
用来显示Java进程。
jstack
主要用来做线程堆栈分析,常用来分析CPU和load高的问题,一般步骤如下:
- 找到java进程的pid
ps -ef | grep java
- 找到Java进程中的占用cpu较高的线程的线程id
top –Hp pid
- java进程的信息dump到本地文件中 命令:
jstack -l -m pid > dump.txt
jstack线程信息dump内容的线程ID是十六进制,top命令获取查询到的线程id是十进制,需要做一次转换,可以直接使用命令printf "%0x\n" thread_id
来转。
命令行参数选项说明如下:
-l long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
-m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
dump文件里,值得关注的线程状态有:
死锁,Deadlock(重点关注)
执行中,Runnable
等待资源,Waiting on condition(重点关注)
等待获取监视器,Waiting on monitor entry(重点关注)
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING
阻塞,Blocked(重点关注)
停止,Parked
jmap
jmap用来查看堆内存使用状况
内存堆栈
jmap -heap pid
查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
类加载器信息
jmap -permstat pid
打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息
内存对象统计
jmap -histo:live pid
查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象
dump信息分析
jmap -dump:file=/home/admin/jvm.log,live
把进程内存使用情况dump到文件中,可以使用MAT工具来分析
jstat
jstat用于展现jvm的性能统计数据
jstat -gc pid
比如:
root@centos7:/# jstat -gc 21711
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGC FGCT GCT
192.0 192.0 6144.0 1854.9 32000.0 4111.6 55296.0 25472.7 0.431 0.218 0.649
192.0 192.0 6144.0 1972.2 32000.0 4111.6 55296.0 25472.7 0.431 0.218 0.649
先看JVM堆内存布局
堆内存 = 年轻代 + 年老代 + 永久代
年轻代 = Eden区 + 两个Survivor区(和To)
解释各列含义:
S0C、S1C、S0U、S1U:Survivor 0/1区容量(Capacity)和使用量(Used)
EC、EU:Eden区容量和使用量
OC、OU:年老代容量和使用量
PC、PU:永久代容量和使用量
YGC、YGT:年轻代GC次数和GC耗时
FGC、FGCT:Full GC次数和Full GC耗时
GCT:GC总耗时
jcmd
1、查看已有java进程的jvm参数
jcmd 26873 VM.flags
输出:
26873:
-XX:CICompilerCount=2 -XX:InitialHeapSize=33554432 -XX:MaxHeapSize=526385152 -XX:MaxNewSize=175112192 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=11010048 -XX:OldSize=22544384 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC
2、查看所有System.getProperties()信息
jcmd process_id VM.system_properties
3、查看虚拟机版本及命令行
jcmd process_id VM.version
jcmd process_id VM.command_line
4、jinfo命令
jinfo process_id
同jcmd process_id VM.system_properties 和 jcmd process_id VM.command_line