引用计数算法的优缺点 #
从算法描述中容易推知,引用计数具备以下优点:
- 可以立即回收垃圾。因为每个对象在被引用次数为 0 的时候,是立即就可以知道的,所以一旦一个对象成为垃圾,它将立即被释放;
- 没有暂停时间。对象的回收根本不需要另外的 GC 线程专门去做,业务线程自己就搞定了,所以引用计数算法不需要停顿时间。
同时,引用计数也存在以下缺点:
- 在每次赋值操作的时候都要做额外的计算。在多线程的情况下,为了正确地维护引用计数,需要同步和互斥操作,这往往需要通过锁来实现,这会对多线程程序性能带来比较大的损失;
- 会有链式回收的情况。比如多个对象对链表形式串在一起,它们的引用计数都为 1,当链表头被回收时,整个链表都会回收,这可能会导致一次回收所使用的时间过长;
- 循环引用。如果 objA 引用了 objB,objB 也引用了 objA,但是除此之外,再没有其他的地方引用这两个对象了,这两个对象的引用计数就都是 1。这种情况下,这两个对象是不能被回收的。如果说上面两条缺陷还可以克服的话,那么循环引用就是比较致命的。
在使用引用计数算法进行内存管理的语言中,比如 Python 和 Swift,都会存在循环引用的问题。Python 在引用计数之外,另外引入了三色标记算法,保证了在出现循环引用的情况下,垃圾对象也能被正常回收。