java启动参数内可以指定gc的方式,实际情况中参数比较多,摘出部分参数看一下
A: -XX:+UseG1GC -XX:MaxGCPauseMillis=200
B: -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSInitiatingOccupancyOnly
上述两个情况分别简称为A,B。
对于B使用的gc方法是CMS,对于A使用的G1。
-
注意1:内存结构
需要注意一下,对于CMS的内存结构是这样的
但是对于G1,内存划分不是整块整块的,而是把整个内存一整块堆切分成2000个小region,然后年轻代和年老代混排,对于G1,幸存者区域只有一个,所以在执行"jstat -gc"的时候,会看到S0总是空的。【参考资料2,3】
-
注意2
jstat -gc <pid>输出的信息单位是KB不是字节
-
注意3 gc触发的条件
gc条件比较多,说一下常见的条件
对于CMS,伊甸园区满了就会GC
对于G1,伊甸园区满了就会GC,另外还有一个参数控制,当整个堆内存达到一定比例就会GC,InitiatingHeapOccupancyPercent。
-
注意4 G1 gc的模式
G1中提供了三种模式垃圾回收模式,young gc、mixed gc 和 full gc,在不同的条件下被触发。
1、Young gc
eden region被耗尽无法申请内存时,就会触发一次young gc
2、Mixed gc
当越来越多的对象晋升到老年代old region时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即mixed gc
阈值参数 -XX:InitiatingHeapOccupancyPercent,整个堆大小百分比达到该阈值时,会触发一次mixed gc
3、Full gc
老年代被填满,就会触发一次full gc,G1的full gc算法就是单线程执行的serial old gc,会导致异常长时间的暂停时间
参考资料:
https://www.cnblogs.com/hunrry/p/9210022.html
https://hllvm-group.iteye.com/group/topic/42352
http://blog.didispace.com/step-by-step-g1/
https://www.jianshu.com/p/0f1f5adffdc1
https://blog.51cto.com/janephp/2428670
【参考资料2】
因为G1的堆布局跟HotSpot VM里其它GC不一样——它只有一组逻辑上的survivor space,而不像其它HotSpot GC一样有两段明确、固定的地址空间用作survivor space——所以用jstat看G1的话肯定是survivor space 0显示0%,survivor space 1显示100%。这个是正常的。
您看G1在初始化jstat用的计数器的时候就指定了s0永远是0: