JVM优化——JVM优化工具介绍(8)

在JVM运行的过程中,为保证其稳定、高效或在出现GC问题时分析问题原因,我们需要对GC进行监控。所谓监控,其实就是分析清楚当前GC的情况。其目的是鉴别JVM是否在高效的进行垃圾回收,以及有没有必要进行调优。通过监控GC,我们可以搞清楚很多问题,如:

  1. minor GC和major GC的频率;
  2. 执行一次GC所消耗的时间;
  3. 新生代的对象何时被移到老生代以及花费了多少时间;
  4. 每次GC中,其它线程暂停(Stop the world)的时间;
  5. 每次GC的效果如何,是否不理想;

监控GC的工具分为2种:命令行工具和图形工具;

下面我们主要讲解一下命令行工具,常用的命令行工具有:

  1. jps(JVM Process Status Tool)
  2. jstat(JVM Statistics Monitoring Tool)
  3. jinfo(Configuration Info for Java)
  4. jmap(Memory Map for Java)
  5. jhat(JVM Heap Dump Browser)
  6. jstack(Stack Trace for Java)

注:以上6个命令都在JAVA_HOME/bin中,是Java自带的命令。如果您发现无法使用,请直接进入Java安装目录调用或者先设置Java的环境变量,在windows下,部分命令的部分选项不能使用。

1. jps

jps命令用于查询正在运行的JVM进程,常用的参数为:

-q:只输出LVMID,省略主类的名称
-m:输出虚拟机进程启动时传给主类main()函数的参数
-l:输出主类的全类名,如果进程执行的是Jar包,输出Jar路径
-v:输出虚拟机进程启动时JVM参数

命令格式:jps [option] [hostid]

2. jstat

jstat可以实时显示本地或远程JVM进程中类装载、内存、垃圾收集、JIT编译等数据(如果要显示远程JVM信息,需要远程主机开启RMI支持)。
如果在服务启动时没有指定启动参数-verbose:gc,则可以用jstat实时查看gc情况。

jstat常用选项如下:

-class:监视类装载、卸载数量、总空间及类装载所耗费的时间
-gc:监听Java堆状况,包括Eden区、两个Survivor区、老年代、永久代等的容量,以用空间、GC时间合计等信息
-gccapacity:监视内容与-gc基本相同,但输出主要关注java堆各个区域使用到的最大和最小空间
-gcutil:监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause:与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew:监视新生代GC状况
-gcnewcapacity:监视内同与-gcnew基本相同,输出主要关注使用到的最大和最小空间
-gcold:监视老年代GC情况
-gcoldcapacity:监视内同与-gcold基本相同,输出主要关注使用到的最大和最小空间
-gcpermcapacity:输出永久代使用到最大和最小空间
-compiler:输出JIT编译器编译过的方法、耗时等信息
-printcompilation:输出已经被JIT编译的方法

命令格式:jstat [option vmid [interval [count]]]

如图:jstat实例代码
在图中,命令jstat -gc 5579 1000 10代表着:搜集vid为5579的java进程的整体gc状态, 每1s收集一次,共收集5次;
各列解释如下:
S0C:S0区容量(S1区相同,略)
S0U:S0区已使用
EC:Eden区容量
EU:Eden区已使用
OC:老年代容量
OU:老年代已使用
PC:Perm容量
PU:Perm区已使用
MC: Metaspace容量(JDK1.8)
MU: Metaspace使用(JDK1.8)
YGC:Young GC(Minor GC)次数
YGCT:Young GC总耗时
FGC:Full GC(major GC)次数
FGCT:Full GC总耗时
GCT:GC总耗时

3. jinfo

用于查询当前运行这的JVM属性和参数的值。jinfo可以使用如下选项:

-flag vmName : 显示指定的参数的系统默认值
-flag [+|-]name : 启用或者禁用某项参数
-flag name=value : 修改VM参数值
-sysprops:打印虚拟机进程的System.getProperties()

命令格式:jinfo [option] pid

4. jmap

用于显示当前Java堆和永久代的详细信息(如当前使用的收集器,当前的空间使用率等)
-heap:显示java堆详细信息(只在Linux/Solaris下有效)
-dump:生成java堆转储快照
-histo[:live]:显示堆中对象统计信息,如果加入live选项则只统计活着的对象信息
-F:当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生成dump快照(只在Linux/Solaris下有效)
-finalizerinfo:显示在F-Queue中等待Finalizer线程执行finalize方法的对象(只在Linux/Solaris下有效)
命令格式:jmap [option] PID

其中前面3个参数最重要,如:
查看对详细信息:jmap -heap 5579
生成dump文件:jmap -dump:format=b,file=文件名.hprof 5579
查看当前堆中对象统计信息:jmap -histo 5579:该命令显示3列,分别为对象数量,对象大小,对象名称,通过该命令可以查看是否内存中有大对象;

5. jhat

用于分析使用jmap生成的dump文件,是JDK自带的工具,使用方法为: jhat -J -Xmx512m [file]
不过jhat没有mat好用,推荐使用mat(Eclipse插件: http://www.eclipse.org/mat ),mat速度更快,而且是图形界面。

6. jstack

用于生成当前JVM的所有线程快照,线程快照是虚拟机每一条线程正在执行的方法,目的是定位线程出现长时间停顿的原因。

-F:当正常输出的请求不被响应时,强制输出线程堆栈
-l:除堆栈外,显示关于锁的附加信息
-m:如果调用到本地方法的话,可以显示C/C++的堆栈(混合模式)

命令格式:jstack [option] vmid

坚持原创技术分享,您的支持将鼓励我的继续创作