垃圾回收的引用计数器算法详解

快乐打工仔 分类:实例代码

垃圾回收的引用计数器算法详解属于前端实例代码,有关更多实例代码大家可以查看

本章节结合图示介绍一下垃圾回收的引用计数算法,需要的朋友可以做一下参考。

关于标记清除算法可以参阅垃圾回收的标记清除算法详解一章节。

一.基本概念:

为每个对象增加一个字段记录被引用的次数,并由运行时跟踪和更新引用的总数。

看如下代码实例:

var antzone = new Antzone("犀牛前端部落");
var obj = antzone;

上面的代码中,我们实例化一个对象,并将其赋值给变量antzone,这个时候antzone引用了对象,计数器的值为1。

然后我将antzone赋值给变量obj,这时候已经有两个变量引用对象了,所以计数器的值变为2。

图示如下:

前端教程

图示1,计数器的值为1。

前端教程

图示2,计数器的值为2。

由上面的代码可以看出,引用类型每次赋值都需要运行时更新计数器,运行时的更新代码可能如下:

if(antzone != obj){
  if (antzone != null)
    --antzone.refCount;
  antzone = obj;
  if (antzone != null)
    ++antzone.refCount;
}

二.计数器算法优点:

此算法的一大优点是无需等待内存耗尽再执行垃圾回收操作,其可以在赋值操作的同时,检查计数器是否为0,如果是的话就可以立即回收;运行时的代码可能如下:

if (antzone != obj) {
  if (antzone != null)
    if (--antzone.refCount == 0)
      heap.Release(antzone);
 
  antzone = obj;
  if (antzone != null)
    ++antzone.refCount;
}

三.计数器算法的缺点:

此算法不能解决循环引用的问题,如下图,构造了一个列表,将最后一个元素的next属性指向第一个元素,即引用第一个元素,从而构成循环引用;这个时候如果我们将列表的头head赋值为null,此时列表的各个元素的计数器都不为0,同时我们也失去了对列表的引用控制,从而导致列表元素不能被回收。

前端教程

四.引用计数算法的特点:

(1).需要单独的字段存储计数器,增加了存储空间的开销。

(2).每次赋值都需要更新计数器,增加了时间开销。

(3).垃圾对象便于辨识,只要计数器为0,就可作为垃圾回收。

(4).及时回收垃圾,没有延迟性。

(5).不能解决循环引用的问题。

垃圾回收的引用计数器算法详解,这样的场景在实际项目中还是用的比较多的,关于垃圾回收的引用计数器算法详解就介绍到这了。

回复

我来回复
  • 暂无回复内容