介绍一下G1垃圾收集器
G1收集器伴随JAVA9于2017-9-21发布,G1收集器兼顾
低延迟和高吞吐在服务端运行,HotSpot团队期望取代CMS收集器。也就是在满足停顿时间的情况下获取最大的吞度量。有两种收集模式Young GC和Mixed GC。G1收集器将堆内存划分成大小相等的Region,新生代,老年代也就成了逻辑概念。整体上采用的是标记-整理算法,局部采用了复制算法。
G1是jdk1.9的默认垃圾收集器,-XX:+UseG1GC开启
G1收集器Region的类型
- 新生代
- 老年代
- 未使用
- 大对象区
新生代,老年代的Region不再是一块连续的空间。当然存放大对象的Region必须要连续。
G1收集器中大对象怎么分配
- 对象的大小<0.5个RegionSize直接存在新生代
Eden Region区 - 对象的大小>=0.5个RegionSize且对象的大小<1个RegionSize,存到大对象区
Humongous Region - 对象的大小>=1个
RegionSize存到连续的大对象区Humongous Region
怎么指定Region的大小
使用
-XX:G1HeapRegionSize来指定Region的大小,Region的大小必须是2的幂次方,最大32M。
G1垃圾收集器的运行过程?
初始标记(stop the world)
比较
GC Roots直接引用的对象同时标记,同时标记GC Roots对象所在的Region称为Root Region
根分区扫描
扫描整个老年代
Region的Rset,标记包含初始标记阶段的Root Region的Region
并发标记
遍历
根分区扫描步骤标记好Region,标记所有可达对象,和应用线程并发执行
重新标记(stop the world)
由于
并发标记是和应用线程并发执行的,所以不可避免的有些对象会发生变化,G1 GC清空 SATB缓冲区,跟踪未被访问的存活对象,并执行引用处理。
选择清除(stop the world)
评估每个
Region的垃圾量,选取回收效果最好的若干Region收集(取决于-XX:MaxGCPauseMillis设置值,默认是200ms)。在规定停顿时间内,获取最大的吞吐量。
什么是Rset
每个
Region初始化时,都会初始化一个Rset(remembered set),每个Region都包含一个Rset,Rset的作用是记录了哪些内存区域(Region)堆当前Region的引用。Rset是一个空间换时间的数据结构。有了Rset可以避免对整个堆进行扫描。
G1和CMS的区别
- G1采用
标记-整理算法,CMS采用标记-清除算法,所以G1不会产生很多垃圾碎片. - G1的STW(stop the world)可控,可以使用
-XX:MaxGCPauseMillis设置默认200ms - G1的
Young GC模式可以工作在年轻代,而单独的CMS只能工作在老年代.
G1的应用场景
- 服务端多核CPU,JVM占用较大的应用(至少大于4G)。
- 应用在运行过程中产生大量的碎片,需要经常压缩。
- 想要更可控,可预期的停顿时间;防止高并发下应用雪崩现象。