[讨论] [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,那也不是啥好事。如果你们的目标就要定那么低那我只能说你们的目标自身就不合理。 |