[讨论] 关于GC参数的问题

myali88 2011-09-20
我在http://blogs.oracle.com/jonthecollector/entry/our_collectors ,里看到
引用

Using the -XX flags for our collectors for jdk6,

UseSerialGC is "Serial" + "Serial Old"
UseParNewGC is "ParNew" + "Serial Old"
UseConcMarkSweepGC is "ParNew" + "CMS" + "Serial Old". "CMS" is used most of the time to collect the tenured generation. "Serial Old" is used when a concurrent mode failure occurs.
UseParallelGC is "Parallel Scavenge" + "Serial Old"
UseParallelOldGC is "Parallel Scavenge" + "Parallel Old"

这么一段,但我实际使用jdk 6设置相应的参数后,通过jconsole看到的GC组合好像和这里说的不一样,比如:
针对UseParallelGC ,可以看到:
引用

GC 时间:
PS MarkSweep(1 项收集)所用的时间为        0.249 秒
PS Scavenge(15 项收集)所用的时间为        0.302


我的问题是:
1、是否可以直接通过jconsole上显示的GC信息判断GC是什么类型,比如“PS MarkSweep”和“PS Scavenge”我就认为是“Parallel”的?
2、如果可以,那么是否作者的说明有问题呢:
引用
UseParallelGC is "Parallel Scavenge" + "Serial Old"
,这里应该两个都是“Parallel”的?
RednaxelaFX 2011-09-20
其实是这样:链接所引用的那篇文章里的图是个简化的示意图,实际上在HotSpot VM内因为历史原因情况稍微复杂一些。

HotSpot VM里多个GC有部分共享的代码。有一个分代式GC框架,Serial/Serial Old/ParNew/CMS都在这个框架内;在该框架内的young collector和old collector可以任意搭配使用,所谓的“mix-and-match”。
而ParallelScavenge与G1则不在这个框架内,而是各自采用了自己特别的框架。这是因为新的GC实现时发现原本的分代式GC框架用起来不顺手。请参考官方文档的Collector Styles一段。

ParallelScavenge(PS)的young collector就如其名字所示,是并行的拷贝式收集器。本来这个young collector就是“Parallel Scavenge”所指,但因为它不兼容原本的分代式GC框架,为了凸显出它是不同的,所以它的young collector带上了PS前缀,全名变成PS Scavenge。对应的,它的old collector的名字也带上了PS前缀,叫做PS MarkSweep。
这个PS MarkSweep默认的实现实际上是一层皮,它底下真正做mark-sweep-compact工作的代码是跟分代式GC框架里的serial old(这个collector名字叫做MarkSweepCompact)是共用同一份代码的。也就是说实际上PS MarkSweep与MarkSweepCompact在HotSpot VM里是同一个collector实现,包了两张不同的皮;这个collector是串行的。

在顶楼链接里的那帖就是基于这个事实,而将两者简单的一并描述为“serial old”。

能与PS系兼容的并行old collector可以通过-XX:+UseParallelOldGC来开启,但(不幸的是)它的collector名字显示出来也是PS MarkSweep。

还有这种代码增添混乱程度:
inline const char* PSOldGen::select_name() {
  return UseParallelOldGC ? "ParOldGen" : "PSOldGen";
}


本来这状况就挺混乱了,其实也没必要太纠结,呵呵。
myali88 2011-09-21
谢谢!本来对JVM内部使用的GC就不是很清楚,这样的命名更使人迷惑,还好你来解释了一下。

其实,我注意不是关注GC本身的名字,而是想总结一下到底HotSpot里面有哪几种GC,看了些文档好像都没有一个同一的说明,GC划分的标准也各不一样,
有说按收集算法的:引用计算和跟踪;
有说按运行方式的:串行、并行和并发;
有说按性能指标的:throughput collector,concurrent low pause collector,ncremental (sometimes called train) low pause collector。

不知道@RednaxelaFX是否有过这样的总结,这些不同的划分和上面提到的Serial/Serial Old/ParNew/CMS 或 PS Scavenge PS MarkSweep是怎么对应的?
RednaxelaFX 2011-09-21
HotSpot VM的全部GC都是tracing的,没有用reference counting。

串行、并行、并发都有。

serial/serial old(包括PS Scavenge的非并行版)/CMS的concurrent mode failure这几种是串行的
ParNew/PS Scavenge/ParallelOld是并行的;CMS也有部分阶段是并行的(parallel remark),并且可以通过参数将并发的部分也并行化(不过默认不是并行的,-XX:ConcGCThreads)
CMS的普通周期的并发的
G1是默认就既并行也并发的(并行是说GC自己的工作用多线程同时去做,并发是说GC与应用的工作可以都在进行)

Train已经扔掉了,它的替代品是CMS,而G1有望在未来替代CMS。

ParallelScavenge是throughput collector
CMS是low pause,G1是low pause + incremental
Global site tag (gtag.js) - Google Analytics