Home > php教程 > php手册 > Java GC专家系列2:Java 垃圾回收的监控

Java GC专家系列2:Java 垃圾回收的监控

WBOY
Release: 2016-06-01 09:46:41
Original
1198 people have browsed it

在本篇中,我将介绍JVM在真实环境中如何运行GC的。

 

什么是GC监控

GC监控 指的是在运行时跟踪JVM运行GC的过程。例如,通过GC监控,我们能找出:

  1. 何时新生代的对象会被移动到老年代,有多少对象被移到了老年代。
  2. 何时stop-the-world发生以及持续时间。

通过GC监控,能发现JVM是否在有效的运行GC以及是否需要额外的GC调优。基于这些信息,我们可以通过优化应用或者改变GC运行方式(GC调优),从而提高应用性能。

 

如何做GC监控

GC监控的方式很多,区别在于GC操作信息的展示会有所不同。GC是由JVM触发,因为GC监控工具展示的信息都是由JVM提供,所以不管使用哪种方式做GC监控,最终获取的信息都是一致的。因此,没有必要深入学习每种GC监控工具,只需要花些时间学习每种工具的使用方法,能够在不同的场合选择合适的工具即可。

因为JVM规范没有要求暴露GC信息的标准方法,所以下面列出的工具或JVM选项并不能适用于所有不同的JVM实现。在下面的介绍中都是基于Hotspot JVM(Oracle JVM)进行。因为NHN使用的是Oracle(Sun) JVM,所以在使用以下工具或JVM选项时并不会太困难。

首先,GC监控工具根据访问接口和方式不同分为CUIGUI。经典的CUI 工具可以使用一个单独的CUI应用jstat,也可以在运行JVM时通过提供”-verbosegc“选项来实现。

GUI GC监控工具通过单独的GUI应用来实现,后面会介绍三个常用的GUI GC工具:jconsole, jvisualvm和Visual GC。

下面开始学习每一种GC监控方法:

 

jstat

jstat是Hotspot JVM内置的监控工具。Hotspot JVM还内置了其他监控工具如jpsjstatd。有时候需要这三种工具一起来监控Java应用的运行。

jstat 不只提供GC操作的相关信息,也还提供类加载和即时编译器相关的操作信息。尽管如此,本文我们只会涉及jstat提供的GC操作相关的功能。

jstat 位于$JDK_HOME/bin目录,如果java或javac命令能够正常运行,jstat命令也应该能够运行。

你可以在命令行中尝试一下:

<code>$> jstat –gc  $<vmid> 1000

S0C       S1C       S0U    S1U      EC         EU          OC         OU         PC         PU         YGC     YGCT    FGC      FGCT     GCT
3008.0   3072.0    0.0     1511.1   343360.0   46383.0     699072.0   283690.2   75392.0    41064.3    2540    18.454    4      1.133    19.588
3008.0   3072.0    0.0     1511.1   343360.0   47530.9     699072.0   283690.2   75392.0    41064.3    2540    18.454    4      1.133    19.588
3008.0   3072.0    0.0     1511.1   343360.0   47793.0     699072.0   283690.2   75392.0    41064.3    2540    18.454    4      1.133    19.588

$></vmid></code>
Copy after login

如上所示,真实的内存各部分数据情况按以下各列顺序列出:

<code>SOC        S1C        S0U        S1U        EC        EU        OU        PC</code>
Copy after login

 

vmid(虚拟机id: Virtual Machine ID),见名示意,表示VM的ID。运行在本地或远程的虚拟机都可以通过vmid指定。运行在本地虚拟机上的Java应用的vmid又称为lvmid(Local vmid),通常与PID相同。虽然可以通过ps命令或Windows的任务管理器查看PID的值从而得到lvmid,但更推荐使用jps,因为PID和lvmid之间并不总是一一对应。jps表示Java PS。正如ps命令可以看到PIDs和进程名,通过jps可以看到vmids和main方法信息。

通过jps找到你要监控的Java应用的vmid,然后作为jstat的参数即可。如果多个WAS实例运行在同一设备上时,如果只使用jps命令只能找到引导程序的信息。这时候就要ps -ef | grep java命令和jps命令一起使用。

GC性能数据需要持续观察,因此在运行jstat时需要定时输出GC的监控信息。

举例来说:运行jstat -gc <vmid> 1000</vmid>(or 1s)将会每隔1s在控制台上输出一次GC数据。jstat -gc <vmid> 1000 10</vmid>将会每隔1s输出一次GC数据,总共输出10次。

与GC相关的选项除了-gc,还有其他一些,如下表所示:

选项名称 描述
gc 输出堆空间上各分区当前的大小及使用量(Ede, Survivor, Old等),GC执行的总次数以及累积消耗的执行时长。
gccapacity 输出堆空间上各分区的最小和最大容量,当前大小,每个区上的GC执行次数(不输出当前使用量和累积的GC耗时)。
gccause 除了输出 -gcutil提供的信息外,还会输出最后一次GC和当前GC的原因。
gcnew 新生代上的GC性能数据。
gcnewcapacity 新生代容量的统计信息。
gcold 老年代的GC性能数据。
gcoldcapacity 老年代容量的统计信息。
gcpermcapacity 持久代(方法区)上的统计信息。
gcutil 以%的格式输出每个分区的使用量。同时也会输出GC执行的总次数及累积耗时。

如果只关心GC频率,通常使用-gcutil(或者 -gccause), -gc-gccapacity即可。

  • -gcutil 用于检测各区上的使用量,GC执行次数以及累积耗时,
  • -gccapacity 和其他的几个选项可用于输出实际已分配的内存大小。

使用-gc选项的输出如下:

<code class="language-html">S0C         S1C    …    GCT
1248.0     896.0    …    1.246
1248.0      896.0    …    1.246
…         …        …    …</code>
Copy after login

给jstat指定不同的选项会列出不同的列,如下列所示。表格右侧列出了会输出此信息的jstat选项。

数据列 描述 支持的jstat 选项
S0C Survivor0的当前容量 -gc
-gccapacity
-gcnew
-gcnewcapacity
S1C S1的当前容量 -gc
-gccapacity
-gcnew
-gcnewcapacity
S0U S0的使用量 -gc
-gcnew
S1U S1的使用量 -gc
-gcnew
EC Eden区的当前容量 -gc
-gccapacity
-gcnew
-gcnewcapacity
EU Eden区的使用量 -gc
-gcnew
OC old区的当前容量 -gc
-gccapacity
-gcnew
-gcnewcapacity
OU old区的使用量 -gc
-gcnew
PC 方法区的当前容量 -gc
-gccapacity
-gcold
-gcoldcapacity
-gcpermcapacity
PU 方法区的使用量 -gc
-gcold
YGC Young GC次数 -gc
-gccapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
YGCT Young GC累积耗时 -gc
-gcnew
-gcutil
-gccause
FGC Full GC次数 -gc
-gccapacity
-gcnew
-gcnewcapacity
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
FGCT Full GC累积耗时 -gc
-gcold
-gcoldcapacity
-gcpermcapacity
-gcutil
-gccause
GCT GC总的累积耗时 -gc
-gcold
-gcoldcapacity
-gccapacity
-gcpermcapacity
-gcutil
-gccause
NGCMN 新生代最小容量 -gccapacity
-gcnewcapacity
NGCMX 新生代最大容量 -gccapacity
-gcnewcapacity
NGC 新生代当前容量 -gccapacity
-gcnewcapacity
OGCMN 老年代最小容量 -gccapacity
-gcoldcapacity
OGCMX 老年代最大容量 -gccapacity
-gcoldcapacity
OGC 老年代当前容量 -gccapacity
-gcoldcapacity
PGCMN 方法区最小容量 -gccapacity
-gcpermcapacity
PGCMX 方法区最大容量 -gccapacity
-gcpermcapacity
PGC 方法区当前容量 -gccapacity
-gcpermcapacity
PC 方法区的当前容量 -gccapacity
-gcpermcapacity
PU 方法区使用量 -gccapacity
-gcold
LGCC 上一次GC发生的原因 -gccause
GCC 当前GC发生的原因 -gccause
TT 存活阀值,如果对象在新生代移动次数超过此阀值,则会被移到老年代 -gcnew
MTT 最大存活阀值,如果对象在新生代移动次数超过此阀值,则会被移到老年代 -gcnew
DSS survivor区的理想容量 -gcnew

表格中容量数量单位为:KB

jstat的优点在于不管是本地还是远程Java应用,你都可以通过jstat命令查看GC操作相关的数据,并通过控制台输出这些信息。在使用-gcutil选项时,会输出如下字段的信息。在做GC调优时,尤其要关注YGCYGCTFGCFGCTGCT的数据变化。

<code>S0      S1       E        O        P        YGC    YGCT     FGC    FGCT     GCT
0.00    66.44    54.12    10.58    86.63    217    0.928     2     0.067    0.995
0.00    66.44    54.12    10.58    86.63    217    0.928     2     0.067    0.995
0.00    66.44    54.12    10.58    86.63    217    0.928     2     0.067    0.995</code>
Copy after login

这些信息非常重要,它统计了GC运行时的耗时情况,能反映出GC的性能指标。

在上例中,YGC是217次, YGCT为0.928,平均下来每次young GC耗时4ms(0.004 s)。同样可算出full GC的平均耗时为33ms。

然而平均值对发现实现的GC问题并没有太大的帮助,因为每次GC耗时通常会有巨大的偏差(也就是说,如果full GC的平均值为0.067s,可能意味着其中一次GC耗时1ms,而另外一次持续134ms)。为了能观察每次GC的独立耗时而非平均值,更好的方式是使用-verbosegc

 

-verbosegc

-verbosegc 是运行Java应用时的一个JVM选项。jstat可以监控任何JVM应用而无需指定启动参数,-verbosegc去要在开启应用时就指定好,所以看起来-verbosegc并不是一个必要的选项(因为可以使用jstat完成相同工作)。然而当GC发生时-verbosegc的输出信息更容易理解,这对于监控烦杂的GC信息却大于益处。

  jstat -verbosegc
监控目标 可输出日志到终端上的Java应用或者能通过jstatd连接到网络的远程Java应用 在启动JVM时指定了-verbosegc 参数的Java应用
输出信息 堆状态(使用量、最大容量、GC次数及累积耗时等) 每次GC前后新生代和老年代的容量变化及GC耗时
输出时机 任何指定的时间 任何GC发生时
优势 方便连续观察堆大小的变化 观察单次GC对系统的影响

在使用-verbosegc时还可同时指定以下附加选项:

  • -XX:+PrintGCDetails
  • -XX:+PrintGCTimeStamps
  • -XX:+PrintHeapAtGC
  • -XX:+PrintGCDateStamps(JDK6U4引入的选项)

如果只是指定了-verbosegc选项,则默认会同时指定-XX:+PrintGCDetails。另外,-verbosegc的附加选项都可以组合使用。

使用-verbosegc后,当有minor GC发生时,输出的数据格式如下:

<code class="language-java">[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]</pause></ending></starting></pause></ending></starting></collector></code>
Copy after login
字段 含义
Collector 使用的收集器
starting occupancy1 GC发生前的新生代大小
ending occupancy1 GC后新生代的大小
pause time1 执行minor GC时Java应用停顿的时长
starting occupancy3 GC发生前堆空间总大小
ending occupancy3 GC发生后堆空间总大小
pause time3 执行总体GC(包括Full GC)时Java应用停顿时长

下面是一个Full GC输出的例子:

<code class="language-java">[Full GC [Tenured: 3485K->4095K(4096K), 0.1745373 secs] 61244K->7418K(63104K), [Perm : 10756K->10756K(12288K)], 0.1762129 secs] [Times: user=0.19 sys=0.00, real=0.19 secs]</code>
Copy after login

如果使用了[CMS回收算法](),CMS相关信息也会紧接着提供出来。

因为-verbosegc选项可以把每次GC发生时的信息都以log方式输出,所以很容易观察GC操作关后heap使用率的变化情况。

 

(Java) VisualVM + Visual GC

Java Virsual VM是Oracle JDK提供的一个GUI式的图表/监控工具。

Java GC专家系列2:Java 垃圾回收的监控

图1:VirsualVM 界面

与内置在JDK中的版本不同,你可以在网站上单独下载Virsual VM。方便起见,JDK内置的版本称为Java VirsualVM(jvisualvm),从网站上单独下载的称为Virsual VM(visualvm)。二者之间的特性并不完全一致,在一些方面(例如安装插件等)会有细微的差别。就我个人而言,更偏向于使用单独下载的Virsual VM。

启动Visual VM后,如果你左侧面板上选择了希望监控的应用,就会看到”Monitoring”一栏。从Monitoring栏中可以获得关于GC和内存堆的基本信息。

尽管能通过Visual VM的基本特性得到GC的基本状态,但并不能像使用jstat-verbosegc一样获得更详细的信息。

如果想得到像jstat一样的详细信息,则需要安装相应的Virsual VM插件。可以在Tools菜单里获取Virsual GC插件。

Java GC专家系列2:Java 垃圾回收的监控

图2:Virsual GC安装界面

通过Virsual GC,可以以更直观的方式获得jstatd提供的信息。

Java GC专家系列2:Java 垃圾回收的监控

图3:Virsual GC运行界面

 

HPJMeter

HPJMeter是一个分析-verbosegc输出结果的便捷工具。如果把Visual GC看作是jstat的GUI版本,那么HPJMeter则是-verbosegc的GUI版本。话说回来,GC分析只是HPJMeter提供的众多特性之一。HPJMeter是HP公司开发的一款性能监控工具,可以使用在HP-UX,Linux和MS Windows上。

起初,只是一款叫做HPTune的工具提供GUI的方式分析-verbosegc。自从HPJMeter 3.0开始便集成了HPTune,因此无需再单独下载HPTune。

在应用运行过程中,-verbosegc的输出结果可以重定向到一个单独的文件中。

可以通过HPJMeter打开该文件,然后使用直观的GUI界面便捷的分析GC数据。

Java GC专家系列2:Java 垃圾回收的监控

图4:HPJMeter

 

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template