oracle g1回收器 免费,G1 垃圾回收器的工作流程

与此前其他垃圾回收器一样,G1 回收器也分为对 Eden 区进行的 Young GC 以及对老年代进行 的 Mix GC。

4.1 G1 中的 RSet 与 Card Table

对于只针对新生代或老年代进行的 GC,很显然,不能只扫描对应的分区,因为可能会有老年代对象引用新生代对象或新生代对象引用老年代的对象的情况,这样的话,无论回收哪个分区,都必须要对整个堆内存进行扫描,这显然是过于耗时而不能接受的。

正如我们在介绍 CMS 流程时所介绍的,CMS 通过 RSet 和 Card Table 实现了对上述情况的标记,G1 也使用了类似策略。

RSet 就是 RememberedSet,他跟踪了跨越 heap 区的引用,与 CMS 相反,G1 没有记录当前分区引用了哪些分区,而是在 RSet 中记录了哪些分区引用了当前分区的对象,这是因为 G1 采用细分的 Region 造成分区过多,同时,一个对象可能会引用非常多个对象,如果记录当前分区引用的分区,扫描范围仍然会很大。

但是,光是记录哪些分区引用了当前分区,并且去扫描这些引用了当前分区的分区中的对象,扫描的开销仍然很大,因此 G1 引入了 Card Table,和 CMS 中一样,一个 Card Table 将一个 Region 划分为 128 到 512 字节之间为单位的若干个 Card,通过标记 Card 是否为脏及是否被引用,可以让上述扫描过程进一步精细化。

7af79bba4d58d55eb05ac2aacabf0408.jpg?id=3378643&v=1

4.2 SATB

G1 的回收过程整体上分为标记过程与回收过程,由于标记过程是并发进行的,和 CMS 一样,会在标记过程中产生新的漏标对象,从而可能造成对象被错误地回收掉。

为了避免这种情况的发生,G1 引入了 SATB,他是 Snapshot-At-The-Beginning 的缩写。

SATB 机制维护了一个双向链表,指向每个新分配的对象,这样垃圾回收器可以轻松的知道在开始 GC 后新分配的对象,从而避免对象被误回收,但这样会造成回收过程中产生的新的垃圾对象没有被回收,造成 float garbage。

4.3 Young GC

基于上述的数据结构,Young GC 的主要工作流程是:

标记 -- 扫描静态和本地对象

处理 dirty card,更新 RSet

检测从年轻代指向老年代的对象

对象拷贝

处理软引用、弱引用与虚引用

事实上,回收的重点在于对象拷贝的过程,在这一过程中,G1 将 Eden 区的活跃对象拷贝到 survive 区,如果 survive 区满,则会直接晋升到 old 区,survive 区中经过多次没有回收的对象也会晋升到 old 区。

89a6ccee94117405f519cbe9869d90d4.png?id=3378645&v=1

4.4 Mix GC

Mix GC 是用来对老年代进行回收的,他分为两步:

全局并发标记

拷贝存活对象

全局并发标记共分为五个阶段:

初始标记 -- 对 GC Roots 进行标记,需要 Stop The World

根区域扫描 -- 在初始标记的存活 Region 中扫描对老年代的引用,并标记被引用对象

并发标记 -- 在整个堆中标记存活对象,可中断

最终标记 -- 清空 SATB 缓冲区,跟踪未被访问的存活对象,该阶段需要 Stop The World

清除垃圾 -- 也就是并发清除阶段,在执行 GC 统计和净化 RSet 过程中需要 Stop The World

4.5 Full GC

由于划分 Region,让 G1 更不容易产生内存碎片,但无论如何,内存碎片还是会随着 jvm 的工作而不断产生。

在 Mix GC 之前,老年代已经被填满,或者 Young GC 过程中向老年代晋升的内存分配失败,或者分配巨型对象失败,都会触发串行化的 Full GC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值