来源:http://www.importnew.com/2057.html
成为JavaGC专家Part II — 如何监控Java垃圾回收机制
本文是成为Java GC专家系列文章的第二篇。在第一篇《深入浅出Java垃圾回收机制》中我们学习了不同GC算法的执行过程,GC是如何工作的,什么是新生代和老年代,你应该了解的JDK7中的5种GC类型,以及这5种类型对于应用性能的影响。
在本文中,我将解释JVM到底是如何执行垃圾回收处理的。
什么是GC监控?
垃圾回收收集监控指的是搞清楚JVM如何执行GC的过程,例如,我们可以查明:
1. 何时一个新生代中的对象被移动到老年代时,所花费的时间。
2. Stop-the-world 何时发生的,持续了多长时间。
GC监控是为了鉴别JVM是否在高效地执行GC,以及是否有必要进行额外的性能调优。基于以上信息,我们可以修改应用程序或者调整GC算法(GC优化)。
如何监控GC
有很多种方法可以监控GC,但其差别仅仅是GC操作通过何种方式展现而已。GC操作是由JVM来完成,而GC监控工具只是将JVM提供的GC信息展现给你,因此,不论你使用何种方式监控GC都将得到相同的结果。所以你也就不必去学习所有的监控GC的方法。但是因为学习每种监控方法不会占用太多时间,了解多一点可以帮助你根据不同的场景选择最为合适的方式。
下面所列的工具以及JVM参数并不适用于所有的HVM供应商。这是因为并没有关于GC信息的强制标准。本文我们将使用HotSpot JVM (Oracle JVM)。因为NHN 一直在使用Oracle (Sun) JVM,所以用它作为示例来解释我们提到的工具和JVM参数更容易些。
首先,GC监控方法根据访问的接口不同,可以分成CUI 和GUI 两大类。CUI GC监控方法使用一个独立的叫做”jstat”的CUI应用,或者在启动JVM的时候选择JVM参数”verbosegc”。
GUI GC监控由一个单独的图形化应用来完成,其中三个最常用的应用是”jconsole”, “jvisualvm” 和 “Visual GC”。
下面我们来详细学习每种方法。
jstat
jstat 是HotSpot JVM提供的一个监控工具。其他监控工具还有jps 和jstatd。有些时候,你可能需要同时使用三种工具来监控你的应用。jstat 不仅提供GC操作的信息,还提供类装载操作的信息以及运行时编译器操作的信息。本文将只涉及jstat能够提供的信息中与监控GC操作信息相关的功能。
jstat 被放置在$JDK_HOME/bin。因此只要java 和 javac能执行,jstat 同样可以执行。
你可以在命令行环境下执行如下语句。
1
2
3
4
5
6
7
8
|
$> S0C 3008.0 3008.0 3008.0 $> |
在上图的例子中,实际的数据会按照如下列输出:
1
|
S0C |
vmid (虚拟机 ID),正如其名字描述的,它是虚拟机的ID,Java应用不论运行在本地还是远程的机器都会拥有自己独立的vmid。运行在本地机器上的vmid称之为lvmid (本地vmid),通常是PID。如果想得到PID的值你可以使用ps命令或者windows任务管理器,但我们推荐使用jps来获取,因为PID和lvmid有时会不一致。jps 通过Java PS实现,jps命令会返回vmids和main方法的信息,正如ps命令展现PIDS和进程名字那样。
首先通过jps命令找到你要监控的Java应用的vmid,并把它作为jstat的参数。当几个WAS实例运行在同一台设备上时,如果你只使用jps命令,将只能看到启动(bootstrap)信息。我们建议在这种情况下使用ps -ef | grep java与jps配合使用。
想要得到GC性能相关的数据需要持续不断地监控,因此在执行jstat时,要规则地输出GC监控的信息。
例如,执行”jstat –gc 1000″ (或 1s)会每隔一秒展示GC监控数据。”jstat –gc 1000 10″会每隔1秒展现一次,且一共10次。
参数名称 |
描述 |
gc |
输出每个堆区域的当前可用空间以及已用空间(伊甸园,幸存者等等),GC执行的总次数,GC操作累计所花费的时间。 |
gccapactiy |
输出每个堆区域的最小空间限制(ms)/最大空间限制(mx),当前大小,每个区域之上执行GC的次数。(不输出当前已用空间以及GC执行时间)。 |
gccause |
输出-gcutil提供的信息以及最后一次执行GC的发生原因和当前所执行的GC的发生原因 |
gcnew |
输出新生代空间的GC性能数据 |
gcnewcapacity |
输出新生代空间的大小的统计数据。 |
gcold |
输出老年代空间的GC性能数据。 |
gcoldcapacity |
输出老年代空间的大小的统计数据。 |
gcpermcapacity |
输出持久带空间的大小的统计数据。 |
gcutil |
输出每个堆区域使用占比,以及GC执行的总次数和GC操作所花费的事件。 |
你可以只关心那些最常用的命令,你会经常用到 -gcutil (或-gccause), -gc and –gccapacity。
· -gcutil 被用于检查堆间的使用情况,GC执行的次数以及GC操作所花费的时间。
· -gccapacity以及其他的参数可以用于检查实际分配内存的大小。
使用-gc 参数你可以看到如下输出:
1
2
3
4
|
S0C 1248.0 1248.0 … |
不同的jstat参数输出不同类型的列,如下表所示,根据你使用的”jstat option”会输出不同列的信息。
列 | 说明 | Jstat参数 | ||
S0C | 输出Survivor0空间的大小。单位KB。 |
-gc -gccapacity -gcnew -gcnewcapacity |
||
S1C | 输出Survivor1空间的大小。单位KB。 |
-gc -gccapacity -gcnew -gcnewcapacity |
||
S0U | 输出Survivor0已用空间的大小。单位KB。 |
-gc -gcnew |
||
S1U | 输出Survivor1已用空间的大小。单位KB。 |
-gc -gcnew |
||
EC | 输出Eden空间的大小。单位KB。 |
-gc -gccapacity -gcnew -gcnewcapacity |
||
EU | 输出Eden已用空间的大小。单位KB。 |
-gc -gcnew |
||
OC | 输出老年代空间的大小。单位KB。 |
-gc -gccapacity -gcold -gcoldcapacity |
||
OU | 输出老年代已用空间的大小。单位KB。 |
-gc -gcold |
||
PC | 输出持久代空间的大小。单位KB。 |
-gc -gccapacity -gcold -gcoldcapacity -gcpermcapacity |
||
PU | 输出持久代已用空间的大小。单位KB。 |
-gc -gcold |
||
YGC | 新生代空间GC时间发生的次数。 |
-gc -gccapacity -gcnew -gcnewcapacity -gcold -gcoldcapacity -gcpermcapacity -gcutil -gccause |
||
YGCT | 新生代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 -gcpermcapacity -gcutil -gccause |
||
NGCMN | 新生代最小空间容量,单位KB。 |
-gccapacity |