【004】垃圾回收-引用计数法

GC原本是一种”释放怎么都无法被引用对象的机制“。那么人们自然而然地就会想到,可以让所有对象实现记录下”有多少程序引用自己“。让各对象知道自己的”人气指数“,从而让没有人气的对象自己消失,这就是引用计数法(Reference Counting),它是George E.Collins 于1960年研究出来的。 (60年左右可谓是 垃圾回收算法的元年)。

引用计数法引入了一个概念,那就是”计数器“。计数器表示的是对象的人气指数,也就是有多少程序引用了这个对象(被引用数量)。计数器是无符号的整数,用于计数器的位数根据算法和实现有所不同。

引用计数法怎样进行内存管理?

1.计数器值的增减

在GC标记-清除算法等其他GC算法中,没有分块时mutator会启动GC分配空闲的内存空间。

引用计数法中并没有mutator明确启动GC的语句。引用计数法与mutator的执行密切相关,它在mutator的处理过程中通过增减计数器的值来进行内存管理。

在引用计数法中,除了连接到空闲链表的对象,其他所有对象都是活动对象。

在变更数组元素等的时候会进行指针的更新。通过更新指针,可能会产生没有被任何程序引用的垃圾对象。引用计数法会监督在更新指针的时候是否有产生垃圾,从而在产生垃圾时,将其立刻回收。也就是说,这意味着在分配时没有分块的情况下,堆中的对象都为活动对象,这时候没法新分配对象。

另一方面,GC标记-清除算法即使产生了垃圾也不会将其马上回收,只会在没有分块的时候将垃圾一并回收。像这样,可以说内存管理和mutator同时运行正式引用计数法的一大特征。

3优点

3.1可即刻回收垃圾

在引用计数法中,每个对象始终都知道自己的被引用数(就是计数器的值)。当被引用数的值为0时,对象马上就会把自己作为空闲空间连接到空闲链表。也就是说,各个对象在变成垃圾的同时就会立刻被回收。要说这有什么意义?那就是内存空间不会被垃圾占领。垃圾全部都已经连接到空闲链表,能作为分配在被利用。

另一方面,在其他的GC算法中,及时对象变成了垃圾,程序也无法立刻判别。只有当分块用尽后GC开始执行时,才能知道哪个对象是垃圾,哪个对象不是垃圾。也就是说,知道GC执行前,都会有一部分内存空间被垃圾占用。

3.2最大暂停时间短

在引用计数法中,只有当通过mutator更新指针时程序才会执行垃圾回收。也就是说,每次通过执行mutator生成垃圾时这部分垃圾都会被回收,因而大幅度的消减了mutator的最大暂停时间。

根据mutator的用途不同,最大暂停时间的长短会成为非常重要的因素。

3.3 没有必要沿着指针查找

引用计数法和GC标记-清除算法不一样,没有必要由根沿着指针查询。当我们想减少沿指针查找的次数时,它就派上用场了。

打个比方,在分布式环境中,如果要沿各个计算节点之间的指针进行查找,成本就会增大,因此需要极力控制沿指针查找的次数。

所以,有一种做法是在各个计算节点内回收垃圾时使用GC 标记-清除算法,在考虑到节点间的引用关系时,采用引用计数法。

4.缺点

虽然依据执行的mutator的动作不同而略有差距,我们不能一概而论,不过在大多数情况下,指针都会频繁的更新。特别是有根的指针,会以令人近乎目眩的势头飞速的更新。这是因为根可以通过mutator直接被引用。在引用计数法中,每当指针更新时,计数器值都会伴随着更新。因此,值的增减处理必然会变得繁重。

4.1计数器需要占用很多位

用于引用计数的计数器最大必须能完数完堆中所有对象的引用数。打个比方,假如我们用的是32位的机器,那么就有可能要让2的32次方个对象同时引用一个对象。考虑到这种情况,就有必要确保各对象的计数器有32位大侠。也就是说,对于所有对象,必须保留有32位的空间。这就害的内存空间的使用效率大大降低了。加入对象只有2个域,那么其计数器就占了它整体的1/3.

4.2实现繁琐复杂

引用计数的算法本身简单,但是事实上实现起来却不容易。

4.3 循环引用无法回收

两个对象互相引用,所以各对象的计数器的值都是1.但是这些对象组并没有被其他任何对象引用。因此想一并回收两个对象都不行,只要他们的计数器值都是1,就无法回收。像这样在两个及两个以上的对象相互循环引用形成对象组的情况下,即使这些对象组都成了垃圾,程序也无法将他们回收。

我们列举了很多计数引用法的缺点,那么引用计数法是不是一个”完全没法用的“算法呢?肯定不是呢,事实上,很多处理系统和应用都在使用引用计数法。

要说为什么,那就是因为引用计数法只要稍加改良,就会变得非常具有实用性了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值