垃圾回收算法详解(二)分代垃圾回收算法

概念

首先,“分代垃圾回收”不能单独用来执行 GC。它是用来和之前介绍的基本算法结合在一起使用,来提高那些基本算法的效率的。

也就是说,分代垃圾回收不是跟 ”GC 标记 - 清除算法”和 “GC 复制算法”并列在一起供我们选择的算法,而是需要跟这些基本算法一并使用。

好了,来看看什么是分代垃圾回收算法吧。

首先,为什么会有分代回收的概念呢?

因为人们从众多程序案例中总结出了一个经验:“大部分的对象在生成后马上就变成了垃圾,很少有对象能活得很久。”

那我们对新生成的对象执行GC的频率高,对旧对象执行GC频率低,不就可以提高效率了吗。

于是我们就在对象中导入了“年龄”的概念,经历过一次 GC 后活下来的对象年龄为 1 岁,两次还存活就是2岁,以此类推。

我们把新生成的对象称作新生代,到达一定年龄的对象叫做老年代。

堆空间结构

来看看经典的分代堆示意图:

这里写图片描述

上图中,将堆分为四大部分,1个生成空间、2个幸存空间、1个老年代空间。

其中,2个幸存空间中的1个是”GC复制算法”概念中的From空间、另一个是To空间。

对新生代执行GC时,会将生成空间和幸存空间里的From空间存活对象复制到幸存空间里的To空间。如下图。

新生代空间作用

新生代GC操作的过程:
这里写图片描述

记录集

记录集是干嘛的呢?
在新生代晋升到老年代的时候,老年代中的对象B可能有指向新生代对象A的指针,如果A复制到了老年代空间中成为了A’,那么B中的指向A的指针也要跟着变化。

常规思路是遍历老年代对象,寻找对象内是否保留了指向新生代对象的引用,如果新生代已经晋升,要及时更改引用的指向。

因此,引入了记录集的概念,记录集是记录发出引用的对象,而不是引用的目标对象。见下面图解:

这里写图片描述

上图中,B中引用指向A,记录集记录了A的引用是被B发起的,因此记录集记录了B,即引用发起方。这样,当在A复制到老年代后,只需要通过记录集找到B,并把B的引用改变即可,不需要再去遍历老年代了。

那么,分代回收算法是怎么把老年代中的目标对象记录到记录集中的呢?

答案是:调用write_barrier函数

这里写图片描述

参数 obj 是发出引用的对象, obj 内有要更新的指针,而 field 指的就是 obj 内的域,new_obj 是在指针更新后成为引用目标的对象。
在第 2 行中检查以下 3 点。
• 发出引用的对象是不是老年代对象
• 指针更新后的引用的目标对象是不是新生代对象
• 发出引用的对象是否还没有被记录到记录集中
当这些检查结果都为真时, obj 就被记录到记录集中了。
第 3 行的 $rs_index 是用于新记录对象的索引。
第 7 行则用于更新指针。

对象结构

这里写图片描述

如上图,对象的头部中除了包含对象的种类和大小之外,分代回收算法中还在对象头中包含了age、remembered、forwarded几个部分。其中:

• age:对象的年龄
• forwarded:已经复制完毕的标志
• remembered:已经向记录集记录完毕的标志

需要注意的是:age和forwarded是用于新生代,而remembered只用于老年代。

分配

这里写图片描述

分配函数如上图,没什么好解释的,下面来看看其中的mino_gc()函数是怎么执行的吧。

新生代GC

这里写图片描述

如上图:新生代GC时先将生成空间和幸存From空间内的活动对象复制到幸存To空间,然后利用记录集将老年代中的目标对象的引用修改。最后释放掉生成空间和幸存空间的From空间。伪代码如下:

这里写图片描述
这里写图片描述

如上图:代码比较简单,可能复制一点的就是copy()函数。来看看copy()具体干了啥。

这里写图片描述

如上图:当对象的年龄未超过指定年龄AGE_MAX时,就会在新生代空间内执行复制操作,如果超过,则执行晋升操作promote(obj)

这里写图片描述
这里写图片描述

如上图,见第2、3、4行,如果老年代空间中没有足够空间,则执行老年代GC操作,即major_gc()操作。否则将新生代对象复制到老年代空间中,并遍历其子节点,然后在记录集中记录。

老年代GC

老年代GC就是标记清除算法,不在赘述,有关标记清除法请查阅我的另一篇博文垃圾回收算法详解(一)基础算法

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值