该算法引入一个无符号整形计数器用来统计对象的被引用数,所以该算法中的对象构成是“计数器”+“域” 。该算法没有明确的用来启动 GC 的语句,其通过计数器的增减来管理内存。

计数器更新

  • 在生成新的对象时(new_obj())将域 obj.ref_cnt 设为 1。
  • 更新指针时(update_ptr(ptr, obj))将 obj.ref_cnt++,然后对 ptr 原本指向的对象做减值操作,一旦引用为 0,即回收当前对象,并继续对该对象引用的子对象的引用数做减值,然后将 ptr 指向 obj(*ptr = obj)。

优点

  • 可以立即回收垃圾,一旦引用计数为 0,可以立马将对象作为空闲空间链接到空闲链表。
  • 最大暂停时间短,每次生成垃圾时垃圾都会被回收,缩短了最大暂停时间。
  • 没有必要沿指针查找。

缺点

  • 增减处理繁琐,每当指针更新时,计数器值会随之更新。
  • 计数器占位多,计数器最大必须能够数完堆中所有对象的引用数。如果机器是 32-bit 的,那么就有可能有 2^32 个对象同时引用一个对象,所以每个对象的计数器必须是 32 bits 大。空间利用率太低。
  • 实现繁琐,需要重写所有指针赋值的地方。
  • 循环引用无法回收,两个引用都是 1。