一、引用计数的应用
前面分析过引用计数方法进行GC的优缺点,其中最重要的一个缺点是吞吐量上不去。特别是在内存对象操作频繁并且数量巨大时,更是如此。那么,解决的方法有没有?或者说有没有优化的余地。在前面介绍过一些优化的算法和具体的算法内容,但是有没有可能把引用计数器算法和其它类型的算法融合在一起,做到更优呢?
在2013 年由 Rifat Shahriyar 等人开发的 RC Immix 算 法(Reference Counting Immix)中,使用合并型引用计数法Immix算法(标记-压缩算法)组合起来,形成了一种更高效的GC算法。
二、新的工程优化算法
在上面提到的引用计数器的算法的缺点在于不断的更新引用计数的值,那么这个问题是不是可以用某种方法来减少引用的次数,甚至可不可以将多次的引用计数合并在一起呢?举一个例子,一个指针,A引用B释放,C又引用,D又释放…如此操作,其实对A来说,一直没有变。如果有学过区块链知识的同学可以想到这玩意儿和侧链有点相似啊。确实如此,如果把引用计数器的计算时间维度拉长,而不局限于一次两次之上,在这个更长的时间维度上进行引用计算的清算,就是合并引用计数器算法。
不过有人会提出问题,这个假如在这个过程中,有指针被废弃掉了怎么办?垃圾是不是就无法及时回收。是的,确实如此,在计算机的世界里总是这样,不是牺牲空间就是牺牲时间,没得双全法。为了实现合并计数,还得增加一个引用计数器的注册缓冲区,如此一来,还得多耗费一点内存空间。当这个缓冲区满了以后,就如前面的延迟引用计数器一般,进行GC对其进行搜索,重新重置引用计数器,该回收回收,该继续继续。
所以这个算法的优点是相对于传统的引用计数器GC算法增加了吞吐量,但是这种方法还是增加了暂停的时间,比较难于平衡缓冲区设置大小和时间之间的具体的比例。这就又引用了Immix算法来取长补短即RC Immix算法。
三、具体的实践
RC Immix的具体的方式如下:
1、引用Immix中的线的概念,在此基础上,增加线的引用计数。
2、线的引用计数器上升到活动数量而非整体的引用数量,即活动数量为0即回收(等于变相扩大了粒度)。
3、引用计数算法是无法进行内存对象压缩的,在此算法中为了达到这个目的,引入了限定算法。使用更改缓冲区进行被动碎片整理。
4、对旧对象和循环引用垃圾进行积极的碎片整理,即使用复制算法进行处理。
而对于RC Immix这种算法来说,优点是提高了吞吐量,缺点是增加了暂停时间,同时内存粒度的增大导致了对象回收的不及时,内存利用的效率有所下聊。
四、总结
虽然说工程化是短期内解决问题的一个重要手段,但更强有力的技术进步还是需要靠技术革命。一个新的技术的革命式的跨越发展,带来的社会的变革是深远的,正如计算机,正如核技术等等,在GC这个方向上,还是呼唤有人突破瓶颈,有着翻天覆地的推进。朝代需要高手,时代呼唤高手!