阶段一:默认推荐配置
![](https://img.haomeiwen.com/i14721215/50fa1b06aa7871d6.png)
通过上文对各个GC参数的说明,可以轻松得出第一阶段推荐的参数设置如下,这样的设置基本适用于所有的场景:
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -
XX:+UseCMSCompactAtFullCollection - XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=75%
-XX:-DisableExplicitGC
新生代大小(-Xmn
)调优
- 理论
young区大小直接决定minor gc的频率。minor gc频率 一方面决定单次minor gc的时间长短,gc越频繁,gc时间就越短,gc停顿时间短;一方面决定对象晋升到老年代的量
,gc越频繁
,晋升到老年代的对象量就越大
。解释起来就是:
-
增大young区大小
minor gc频率降低
,单次gc时间会较长
(young区设置更大,一次gc就需要复制更多对象
,耗时必然比较长),业务读写操作延迟抖动较大
。反之,业务读写操作延迟抖动较小,比较平稳。 -
减小young区大小
1.minor gc频率增快,但会加快晋升到老年代的对象总量(每gc一次,对象age就会加一,当age超过阈值就会晋升到老年代,因此gc频率越高
,age就增加越快),潜在增加old gc风险
。
因此设置新生代大小需要进行一定的平衡,不能设置太大,也不能设置太小
- 实验结论
-
图二主要统计Minor GC的主要指标:总GC次数以及平均单次Minor GC耗时。两者来看,更关注后者,因为后者决定了业务读写的延迟以及稳定度;由图中可以看出,Xmn512m的平均单次Minor GC耗时最少,其次是Xmn2g,最差是Xmn5g,达到了130ms左右,意味着在其Minor GC过程中所有业务读写延迟至少为130ms;这个也很好理解,Young区越小,Minor GC频率越高,单次Minor GC需要复制的对象数就越少,耗时越少;
-
图三主要统计CMS GC(老年代GC)的主要指标:CMS GC次数以及平均单次老年代GC耗时(只算STW耗时);由图中可以看出,Xmn2g无论是GC次数还是GC耗时都更加优秀,相比之下Xmn512m就是最差的选择;解释起来也很简单,因为Young区设置太小,Minor GC频率高,对象age增加很快,很多对象就有可能因为age超过阈值(默认6)晋升到老年代,相对而言会更有可能引入大量短寿对象晋升老年代。而短寿对象相对而言会比较小,比如request、response等,大量小对象一旦进入老年代,就会导致CMS GC的时候需要标注更多对象,必然比较耗时;
测试结果基本和理论分析一致,Xmn设置过小会导CMS GC性能较差,而设置过大会导致Minor GC性能较差,因此建议在JVM Heap为64g
以上的情况下设置Xmn在1~3g
之间,在32g
之下设置为512m~1g
;具体最好经过简单的线上调试
;需要特别强调的是,笔者在很多场合都看到很多HBase线上集群会把Xmn设置的很大,比如有些集群Xmx为48g,Xmn为10g,查看日志发现GC性能极差:单次Minor GC基本都在300ms~500ms之间,CMS GC更是很多超过1s。在此强烈建议,将Xmn调大对GC(无论Minor GC还是CMS GC)没有任何好处,不要设置太大
阶段三:增大Survivor区大小(减小SurvivorRatio) & 增大MaxTenuringThreshold
理论分析
上文讲过,一次Minor GC会将存活对象从Eden区(以及survivor from区)复制到Survivor区(to区),因此增大Survivor区可以容纳更多的存活对象。这样就会防止因为Survivor区太小导致很对存活对象还没有达到MaxTenuringThreshold阈值就直接进入老生代,潜在增大old gc的触发频率;但是Survivor区设置太大也会有一定的问题,Survivor设置较大会使得对象可以在Young区’待’的时间很长,但是对于一些长寿对象较多的场景下(比如HBase),大量长寿对象长时间待在Young区做很多’无谓’的复制,一定程度上增加Minor GC开销。
另外,增加MaxTenuringThreshold相当于提高了进入老年代的门槛,可以有效限制进入老年代的对象数。和Survivor设置相似,调整MaxTenuringThreshold也需要做一个取舍,设置太小会增加CMS GC的触发频率以及耗时,而设置太大则会在长寿对象较多场景下增加Minor GC开销。一般情况下,默认MaxTenuringThreshold=15已经相对比较大,不需要做任何调整
- 实验结论
对于Minor GC来说,SurvivorRatio设置对其影响不是很大。而对于CMS GC来说,将SurvivorRatio设置过大简直就是灾难,性能极其差。而和默认值SurvivorRatio=8相比,将SurvivorRatio调小有利于短寿小对象更充分地淘汰,因此建议将SurvivorRatio=2
CMS调优结论
- 缓存模式采用BucketCache策略Offheap模式
- 对于大内存(大于64G),采用如下配置:
-Xmx64g -Xms64g -Xmn2g -Xss256k -XX:MaxPermSize=256m -XX:SurvivorRatio=2 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC
-XX:+CMSParallelRemarkEnabled -XX:MaxTenuringThreshold=15 -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=75 -XX:-DisableExplicitGC
其中Xmn可以随着Java分配堆内存增大而适度增大,但是不能大于4g,取值范围在1~3g范围;SurvivorRatio一般建议选择为2;MaxTenuringThreshold设置为15;
3 对于小内存(小于64G),只需要将上述配置中Xmn改为512m-1g即可
转自
http://hbasefly.com/2016/08/09/hbase-cms-gc/
http://hbasefly.com/2016/05/21/hbase-gc-1/
网友评论