Ruby的GC机制源码分析(2)

来源:互联网 发布:集对分析 知乎 编辑:程序博客网 时间:2024/06/05 07:43

http://aiku.me/bar/10113853

停止与复制

停止与复制型GC 是标记与清除型GC 的一个变体。首先,准备多个对象域。为了简化讨论,假设只有两个域:A 和B 。将一边标记为“active” ,生成的对象都放到active 域中(图5 )。

停止与复制(1) 
图5: 停止与复制(1 )

执行GC 时,按照标记与清除同样的路径进行搜索。但是,与标记不同的是,对象本身移到了另外一个空间(图6 )。搜索全部链接之后,只要抛弃留在A 中的对象,将B 标记为active 即可。

停止与复制(2) 
图6: 停止与复制(2 )

停止与复制也有两个优点。

·         内存回收的同时一并完成压缩。

·         相互引用的对象会聚集在附近,有助于提高缓存的命中率

缺点也是两个。

·         需要两倍以上的对象域

·         对象的位置发生了变化

可见天下没有免费的午餐。

 

引用计数

引用计数不同于之前介绍的东西,它的检查分布在代码各处。

首先,为每个对象加上一个整数计数器。当变量或数组引用时,对象的计数器就会增加。停止引用时,计数器就会随之减少。计数器为0 时,就会释放。这便是引用计数的方法(图7 )。

引用计数 
图7: 引用计数

这种方法有两个优点。

·         GC 的负担分散到整个程序之中

·         不必需的对象能够立刻得到释放

缺点也是两个。

·         容易遗忘对计数器的操作

·         简单的方法无法处理环

这里解释一下第二点。环(cycle )指得是图8 所示的有循环引用关系的状态。变成这样的话,计数器便不会减少,也就绝对无法释放。

环 
图8: 

顺便说一下,最新的Python (2.2 )采用了引用计数,其中的环可以释放。但这并不是引用计数本身的力量,不过是时常采用标记与清除型GC 检查罢了。


0 0
原创粉丝点击