[讨论] [HotSpot VM] G1 垃圾回收的survivor 0区貌似永远是0

stevenprime 2014-10-20
如题,机器内存64G左右,我设置使用G1垃圾回收,参数如下。
-Xms35g -Xmx35g -XX:NewRatio=3 -XX:PermSize=256m -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:GCPauseIntervalMillis=1000 -XX:SurvivorRatio=4 -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:-UseCounterDecay


使用jstat查看垃圾回收情况的时候,为什么s0,s1区总是不变呢?一个是0一个是100

  /home/java/bin/jstat -gcutil pid 1000 1000
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00 100.00  37.35  46.27  10.63      5   10.341     0    0.000   10.341
  0.00 100.00  40.41  46.27  10.63      5   10.341     0    0.000   10.341
  0.00 100.00  43.88  46.27  10.63      5   10.341     0    0.000   10.341
  0.00 100.00  47.76  46.27  10.63      5   10.341     0    0.000   10.341
  0.00 100.00  51.43  46.27  10.63      5   10.341     0    0.000   10.341


------------------

jstat -gcutil 1809  1000 1000
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT   
  0.00 100.00  79.23  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  81.67  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  83.10  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  87.17  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  89.00  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  91.65  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  93.28  65.15  11.00     61   63.283     0    0.000   63.283
  0.00 100.00  94.30  65.15  11.00     62   63.283     0    0.000   63.283
  0.00 100.00   3.64  67.75  11.00     62   63.527     0    0.000   63.527
  0.00 100.00   8.15  67.75  11.00     62   63.527     0    0.000   63.527
  0.00 100.00  11.96  67.75  11.01     62   63.527     0    0.000   63.527


这样可能看清楚一点,ygc前后,s0,s1没有任何改变。我刚开始以为s0,s1太小了,后来设置-XX:SurvivorRatio=4,已经很大了,但是s0,s1还是没有变化,这是为什么呢?
RednaxelaFX 2014-10-21
啊,之前只回复了私信,没看到这边开了一帖。

把私信里写的回复发出来:

您好!

您用的是JDK7u吧?具体版本是多少?

首先请您先读读Monica写的G1调优指南:http://www.oracle.com/technetwork/articles/java/g1gc-1984535.html

然后您指定的VM参数不太合理。-XX:MaxGCPauseMillis=50不是一个很合理的目标(特别是当您的Java heap有35G的时候)。当您给G1指定不合理的目标时,它颇有可能会乱来于是结果还不如给个合理一些的指标好。100ms都好一些。

然后,因为G1的堆布局跟HotSpot VM里其它GC不一样——它只有一组逻辑上的survivor space,而不像其它HotSpot GC一样有两段明确、固定的地址空间用作survivor space——所以用jstat看G1的话肯定是survivor space 0显示0%,survivor space 1显示100%。这个是正常的。

您看G1在初始化jstat用的计数器的时候就指定了s0永远是0:
  //  name "generation.0.space.1"
  // See _old_space_counters for additional counters
  // Set the arguments to indicate that this survivor space is not used.
  _from_counters = new HSpaceCounters("s0", 1 /* ordinal */,
    pad_capacity(0) /* max_capacity */,
    pad_capacity(0) /* init_capacity */,
    _young_collection_counters);

  //  name "generation.0.space.2"
  // See _old_space_counters for additional counters
  _to_counters = new HSpaceCounters("s1", 2 /* ordinal */,
    pad_capacity(overall_reserved()) /* max_capacity */,
    pad_capacity(survivor_space_committed()) /* init_capacity */,
    _young_collection_counters);
stevenprime 2014-10-21
你好,感谢回复,我的jdk版本是1.7.0_51,
还想问三个问题:
1.我看g1 调优里面说,不要给g1设置新生代的大小
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html?cid=6628&ssid=107715905979012

Do not Set Young Generation Size
那为什么还有
-XX:NewRatio=n Ratio of new/old generation sizes. The default value is 2.
这个参数呢?在堆大小一定的情况下,设置了新生代和老年代的比例,那么新生代的大小肯定是固定的

2.既然survivor space和其他垃圾回收算法不一样(看起来好像没有用着),那么为什么还有
-XX:SurvivorRatio=n Ratio of eden/survivor space size. The default value is 8.
这个参数呢?

3.你说我的XX:MaxGCPauseMillis=50 设置得太小了
我的项目是一个垂直搜索引擎,项目设定的目标是响应要在50ms内返回,因此设置了50ms,如果设置得太大,会不会对响应目标造成影响?
RednaxelaFX 2014-10-21
-XX:NewRatio=n
-XX:SurvivorRatio=n

这俩参数都是在G1之前就有的,在HotSpot的其它GC里用没问题;G1只是为了兼容以前的使用习惯才遵循这些老旧参数,实际上它们在G1都是不推荐的(跟G1的自动调整有冲突)。

至于暂停目标的问题,30多G的Xmx要把暂停控制50ms之内对G1来说实在不现实。这样G1很可能会因为跟不上目标而非常频繁的启动GC,那也不是啥好事。如果你们的目标就要定那么低那我只能说你们的目标自身就不合理。
Global site tag (gtag.js) - Google Analytics