【GC Algorithm】引用计数算法
【概述】
引用计数(Reference Counting)算法是每个对象计算指向它的指针的数量,当有一个指针指向自己时计数值加1;当删除一个指向自己的指针时,计数值减1,如果计数值减为0,说明已经不存在指向该对象的指针了,所以它可以被安全的销毁了(回收)。可以很直观的用下面的图表示:
【优点】
1.在于内存管理的开销分布于整个应用程序运行期间,非常的“平滑”,无需挂起应用程序的运行来做垃圾回收;
2.在于空间上的引用局部性比较好,当某个对象的引用计数值变为0时,系统无需访问位于堆中其他页面的单元,而后面我们将要看到的几种垃圾回收算法在回收前都回遍历所有的存活单元,这可能会引起换页(Paging)操作
3.最后引用计数算法提供了一种类似于栈分配的方式,废弃即回收,后面我们将要看到的几种垃圾回收算法在对象废弃后,都会存活一段时间,才会被回收。
【缺点】
1.时间上的开销,每次在对象创建或者释放时,都要计算引用计数值,这会引起一些额外的开销
2.空间上的开销,由于每个对象要保持自己被引用的数量,必须付出额外的空间来存放引用计数值
3.最大的缺点就在于它无法处理环形引用
此处蓝色的这两个对象既不可达也无法回收,因为彼此之间互相引用,它们各自的计数值都不为0,这种情况对引用计数算法来说是无能为力的,而其他的垃圾回收算法却能很好的处理环形引用
【经典案例】
微软的COM技术,IUnknown接口
【评论】
我觉得在所有的垃圾回收算法中,此算法应该是较为容易理解与实现的。同时也很符合C、C++ 这种类型的语言的编程人员的学习思维,毕竟一开始学习就涉及了指针等对内存有直接操作的特性,对于C++而言,智能指针可以算是与这种垃圾回收有着密切的联系(当然不是指STL库中的智能指针)。但正如其第3个缺点,环形引用对于面向对象而言,或者是类似链表的等结构,都会不经意中产生。而如果一旦使用这种垃圾回收算法,前提必将要保证不能出现环形引用,以及产生后应该如何解决。所以有得必有失!
//To be continue...