背景
在一次性能调优中,本来使用的是默认的GC,这里是jdk1.8,年轻代使用的是Parallel Scavenge收集器,老年代使用的是Parallel Old 收集器,后面申请的机器配置降低了一半:2C4G,这时候会发现堆内存会一直增长。
直至触发full gc,再开始下一轮,如此往复,看下tp999。
基本和GC保持一致,看下Parallel Scavenge收集器的回收策略:
通过jmap下载堆内存快照,可以看到老年代使用率越来越高,说明有很多对象直接进入了老年代。其实对于大内存的话,这种情况基本不会出现。
CMS收集器模式
使用-XX:+UseConcMarkSweepGC打开CMS收集器模式,这时候,新生代是ParNew收集器,老年是CMS收集器。这里没有显式的指定新生代的大小,看下切换后效果。
可以看到,中间这段,年轻代gc变的很频繁,并且堆内存使用率也很小,jmap下载堆内存快照,可以看到。
新生代大小只有166M,那么默认值不是说是NewRatio=2,那应该是堆内存的1/3啊,可事实并不是这样的,默认的情况下:
具体可参考源码,这里有篇文章介绍:CMS GC 默认新生代是多大? - 简书CMS GC 默认新生代是多大? 简书 涤生[https://www.jianshu.com/users/150f36a73910/]。转载请注明原创出处,谢谢!如果读完觉得...https://www.jianshu.com/p/832fc4d4cb53
按照这个公式,64M*2*13/10=166.4M,哪确实和事实相符,所以我们在使用CMS收集器模式时,一定要指定新生代的大小,完整参数如下:
这几个参数是必须的。
jdk1.8默认收集器模式
看下jdk1.8默认收集器模式下的新生代大小,也就是年轻代使用的是Parallel Scavenge收集器,老年代使用的是Parallel Old收集器的情况。
我这里是看的4C8G的docker的。