什么是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
|
$> 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
$>
|
在上图的例子中,实际的数据会按照如下列输出:
1
|
S0C S1C S0U S1U EC EU OC OU PC
|
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 S1C … GCT
1248.0 896.0 … 1.246
1248.0 896.0 … 1.246
… … … …
|