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的内存结构是这样的

java gc-LMLPHP

但是对于G1,内存划分不是整块整块的,而是把整个内存一整块堆切分成2000个小region,然后年轻代和年老代混排,对于G1,幸存者区域只有一个,所以在执行"jstat -gc"的时候,会看到S0总是空的。【参考资料2,3】

java gc-LMLPHP

  • 注意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:

11-11 13:46