Java GC(2)—— G1垃圾收集器

1. 简介

Garbage First(简称G1)收集器可以称为垃圾收集器技术史上里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。
Oracle在Jdk7时就将G1收集器作为了hotspot虚拟机的一项重要特征,但直到数年以后的Jdk7 Upate4才移除了实验性标志;此后又经过了一些迭代,到Jdk8 Update40时,G1提供并发的类卸载的支持,补全了计划功能的最后一块拼图,在这之后,G1才称得上是全功能的垃圾收集器
G1的最初目标是取代Jdk5 中发布的CMS收集器,现在已经实现,因为在Jdk9发布时,G1就宣告取代了Parallel Scavenge加Parallel Old的组合,而CMS则被标记为过时的(Deprecate)。
设计者们在设计G1是希望能够设计一款能够建立起“停顿预测模型”的收集器,停顿预测的意思是希望能够在例如M毫秒的时间片段内,消耗不超过N毫秒的垃圾收集时间。为了实现这个目标,首先要改变设计思想,在G1以前的所有其他收集器,垃圾收集的目标范围要么是整个新生代,要么是整个老年代,又或者是全堆收集。G1跳出了这个思路,它可以面向堆的任何部分来组成回收集(Collection Set,一般简称CSet)进行回收,衡量标准不再是它属于哪个分代,而是哪块内存的垃圾数量最多,回收收益最大,这就是G1的Mixed GC模式。

2. 设计思路

G1开创的基于Region的堆内存布局是使它能够实现面向全堆回收的关键。G1仍然遵循了分代收集的理论,但它的内存布局却和之前的其它收集器存在着根本差异:它不再以固定大小和固定数量来划分分代区域,而是把连续的Java堆划分为多个大小相等的独立区域,称为Region,每个Region都可以根据需要来扮演新生代的Eden区,Survivor区,甚至老年代空间。G1再根据不同的分代采取不同的处理策略。这样,不管是新创建的对象,还是已经存货很久的对象都能够获得较好的收集效果。
Region中还有一类比较特殊的区域,称为Humongous,专门用于存储大对象。G1认为只要大小超过了一个Region容量的一半,就判定为大对象。Region的大小可以通过-XX:G1HeapRegionSize来设定,范围是1-32MB,必须是2的整数次幂。对于超过了一整个Region容量的大对象,则使用多个连续的Humongous Region来存储,G1的大多数行为把Humongous Region看作老年代的一部分。

G1将Region作为回收的最小单元,这使得它能够建立可预测的时间停顿模型,这样,每次回收的空间都是Region大小的整数倍,这样就可以有计划地避免在整个Java堆中进行全区域的收集行为。G1可以跟踪评估每个Region里垃圾堆积的价值大小,价值用回收所获得的空间大小以及回收所需要的时间的经验值来衡量,然后在后台维护一个优先级列表,每次根据用户设定允许的收集停顿时间,该参数为-XX:MaxGCPauseMillis来设定,默认值为200ms,优先处理一些回收价值大的Region,这就是为什么G1会称为“Garbage First”。使用Region的划分方式以及优先级列表的回收方式有效保证了G1的回收效率。
将Java堆化整为零听起来是一个很简单的思路,实现起来时却十分复杂:

  • 例如,如何解决众多Region之间的跨区引用?
    这里使用了记忆集(Memory Set)的技术,关于记忆集可以自行百度,总之通过这种方式可以避免将全堆作为扫描GC Roots的对象
  • 再比如,如何保证收集线程和用户线程互不干扰?
    为了解决这个问题,必须首先保证用户线程在改变对象引用关系时,不能破坏原本的对象图结构:CMS收集器采用增量更新算法实现,而G1收集器则是通过原始快照(SATB)算法来实现的。
  • 最后,如何建立起可靠的停顿预测模型呢?
    G1的停顿预测模型是基于衰减均值(Decaying Average)理论来实现的,在收集过程中记录回收每个Region的耗时、每个Region记忆集里脏卡数量等所有可测量的步骤花费的成本,在此之上分析出平均值、标准偏差、置信度等统计信息,根据这些指标,估算一个停顿时间。

3.运行机制

G1的运作过程大致可以分成四步:

  • 初始标记:只标记GC Roots能直接关联到的对象,并修改TAMS指针的值,让下一阶段和用户线程并发运行时能够正确地分配对象空间,该阶段需要停顿线程,但时间极短。
  • 并发标记:开始进行可达性分析,从GC Roots开始扫描整个对象图,找到不可达的对象,该阶段需要较长的时间,但好在可以和用户线程。当扫描完对象图后,还需要重新处理SATB记录下的在并发阶段引用发生变动的对象。
  • 最终标记:用户线程稍作停顿,处理上一阶段有变动的记录。
  • 筛选回收:更新Region的统计数据,并根据其回收价值、回收成本进行排序,根据参数设置的预期时间制定回收计划,复制存活的对象到空的Region中,清除掉所有旧Region,这里由于需要移动存活的对象,所以是必须暂停用户线程的。
    image

4.优点与不足

首先优点:

  1. 可以指定最大停顿时间;
  2. 按收益动态筛选回收集;
  3. 整体来看是基于”标记-整理“,局部上看又是基于”标记-复制“,这使得G1在工作时不会产生内存碎片。

不足:

  1. G1和CMS都使用卡表来处理跨代引用问题,但G1的更为复杂,每个Region都必须有一份卡表,导致占用空间更多,甚至超过20%;作为对比,CMS只需一份卡表,且只需要记录老年代到新生代的引用。
  2. 也是由于更为复杂的卡表,导致G1需要更多的计算资源。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值