引用计数算法

421 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

标记阶段:引用计数算法

主要为了判断对象是否存活

在GC垃圾回收之前,会先判断哪些是存活对象,哪些是已经死亡的对象,被标记为死亡的对象,在GC执行垃圾回收时,会把当前对象所占的内存空间 给释放掉,这个阶段我们称为垃圾标记阶段。

判断对象存活一般有两种方式:引用计数算法和可达性分析算法。

引用计算算法比较简单,对每个对象保存一个整形的引用计数器属性,用来记录对象被引用的情况。

对于一个对象A,只要有任何一个对象引用了A,则A的引用计数器就加1;当引用失效时,引用计数器就减一。

只要对象A的引用计数器的值为0,即表示对象A不可能再被使用,可进行回收。

优点:实现简单,垃圾对象便于辨识,判定效率高,回收没有延迟性。

缺点:

  1. 它需要单独的字段存储计数器,这样的做法增加了存储空间的开销
  2. 每次赋值都需要更新计数器,伴随着加法和减法操作,这增加了时间开销
  3. 引用计数器有一个严重的问题,即无法处理循环引用的情况。这是一条致命缺陷,导致在Java的垃圾回收器中没有使用这类算法。

循环引用问题,GC算法也判断不出来是死亡的对象。 image.png

引用计数算法,是很多语言的资源回收选择,比如Python,它就是使用引用计数算法的。

Python怎么解决这个问题呢?

①手动解除:很好理解,就是在合适的时机,接触引用关系。

②使用弱引用的weakref,weakref是Python提供的标准库,亦在解决循环引用。