当前位置: 首页 > 内存管理 > 正文

内存管理器(二十四)引用计数

引用计数

一种直接的内存清扫方式,通过遍历可以直接的判定一个对象的存活性。

这个思想可以说是非常的简单,有新对象就增加新对象的引用计数,并且减少旧对象的引用计数,当某个引用计数的值为0的时候将它回收。

以上的代码很简单,相信大家都能看明白,有一点是write 这个操作需要保证是原子的,因为很多赋值器和回收器甚至会并发的执行。所以大家一定要做这个“屏障”操作。

引用计数算法的优势:

引用计数算法的回收几乎是很及时的无条件的,只要发现它的引用计数为0则就可以立即回收相关内存,尤其是在一个快要满的堆那是一种极速的回收方式。并且局部性较高。当系统发生部分不可用时也可以回收内存空间,例如分布式系统。

引用计数算法的缺点:

@引用计数系统需要消耗额外的时间开销,由其很有可能对于寄存器以及线程栈也需要引用这样一个开销。

@引用计数的加减必须时原子化的,防止多线程竞争导致对象释放过早。

@只要请求了内存位置就极有可能污染高速缓存。

@无法处理环状的引用的数据结构,例如,孤岛状数据就很难释放。

@停顿时间较长,因为会递归的删出子节点,直接会导致瞬间停顿。

引用计数算法的改进点:

#延时,延时引用计数。

#合并,有时候只需要关心初始和结束状态就可以。

#缓冲,缓冲所有引用计数的增建操作。

#效率低下的本质是,引用计数是全局特征之一,但是通常只有在(线程)局部状态下的操作才有效,以上的操作都是一致的即使“分开时段”操作。

延时引用计数:

只有当赋值器操作堆中对象产生的引用计数操作才会被执行,而栈上和寄存器产生的引用计数便更则会被延时执行。但是此时计数不再准确,需要引入“万物静止”的停顿来定期修正引用计数。

这个思想我在来说说吧:

@分配内存对象,将引用写入根的操作是无屏障的,但是将引用写入堆的时候必须引入屏障,在这种情况下,立即增加新对象的引用计数。当某一个引用计数为0时写屏障需要添加进到零引用表。

@当内存耗尽的时候,就必须进行垃圾回收,回收器需要挂起所有赋值器线程并且检查引用表中对象是否真正为0,只有当被一个或者多个根引用的时候,该对象才能被确定是激活的。

@new -> write ; while (collect == ture)  do collect

 

本文固定链接: http://zmrlinux.com/2016/08/09/%e5%86%85%e5%ad%98%e7%ae%a1%e7%90%86%e5%99%a8%ef%bc%88%e4%ba%8c%e5%8d%81%e5%9b%9b%ef%bc%89%e5%bc%95%e7%94%a8%e8%ae%a1%e6%95%b0/ | Kernel & Me

该日志由 root 于2016年08月09日发表在 内存管理 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 内存管理器(二十四)引用计数 | Kernel & Me