垃圾回收机制的算法实现——保守式垃圾回收算法

本文介绍了内存管理中的保守式和准确式垃圾收集(GC)算法。保守式GC采取宁可误判也不遗漏的策略,通过对齐、堆位置和对象头部判断指针,可能存在误判导致内存泄露。准确式GC则能精确识别指针,采用标记、低位设置和不使用不确定根来实现。保守GC实现简单,但效率较低且有移动对象问题;准确GC效率高但实现复杂。改进方法包括使用句柄和黑名单技术。两种GC各有适用场景,选择需结合实际情况。

一、保守是什么意思

在实际的内存使用中,会出现寄存器、调用栈、全局变量空间等作为GC root即不明确的根,而此时GC是无法识别出当前root是指针还是非指针。
保守,顾名思义,就是宁可漏掉一千,不能错杀一个。这是什么意思呢?学过c/c++都知道,如果有一个整数值,那么这个整数值是指针还是一个具体的数值呢?单纯从这个值本身来看,是无法进行判断的。这也就是保守式GC的原因,遇到这种问题怎么办?保守式GC会利用几种方法来进行判别?
1、是否对齐,这个对齐就是常说的字节对齐,在32位的机器上是4个字节;64位是8个字节。
2、是否指向堆的位置,这个好理解,是否在预告指定的内存堆内,是的话一定是指针。
3、是否是对象的头部,这个和对象对齐有关。
好,既然可以用这几个初步的简单的方法来判断指针和非指针,那么就一定会遇到不属于这三种情况的状况也就是“貌似指针的非指针”。什么意思呢,就是上述三个条件里,有可能都满足但却无法判定,比如有可能出现数值和指向位置重合的情况,那么它到底是指针还是非指针呢?保守式GC就是把它们都当成指针。

二、准确式GC

有保守式GC就会有准确式GC,恰好相反,准确GC可以准确的判断指针和非指针,它使用的判断方法是:
1、做标记,这个方法最简单实用,但可能浪费空间。
2、低1位置位,主要是对数据数值处理时的安全性考虑。
3、不使用保守式GC中的栈、寄存器这类的存储空间为根。

三、特点及改进方法

保守GC的优点:
1、语言处理部分实现容易,基本和GC完全解耦。

保守GC的缺点:
1、对指针和非指针的判断需要成本。
2、错误识别引起内存泄露。
3、在GC算法中由于其自身的特点,应用场景有限。比如因为指针判断问题对象无法移动。

而准确式的GC的优缺点恰好相反,这里就不再赘述。
改进的方法:
对于保守式GC最主要的问题是错误判断指针导致对象的移动产生的不可预测的后果,那么可不可以有一种方式来回避这种情况呢?不知道大家听说过计算机内的一句名言没有:“如果问题不好解决就加一层”。这里也是,增加一个句柄指向对象。这样基本就解决了不可移动的问题。不过,层越多,效率越差。
同样还可以使用黑名单技术,这个就比较好理解了,把相关的模糊的地址名单形成一个黑名单来具体处理。

四、基本应用

保守式GC其实更多是一种策略,而不是一种GC算法。所以从理论讲,只要是符合其应用策略的场景都可以使用。特别是改进后的保守式GC,几乎就可以做为一种完全的策略来使用了。有兴趣可以看看MostlyCopyingGC这个保守式GC的算法。

五、总结

术与道,自古就争论不休。学武术的人都知道一句话“练拳不练功,到老一场空;练功不练拳,好似无舵船”。其实辩证的看问题,在学习上也是一个道理,彼之蜜糖,吾之毒药。一味的单纯指责某个算法好与坏,本身就是一种缘木求鱼的做法。实践是检验真理的唯一标准,实事求是,这才是真正的一种做学问搞技术的态度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值