资讯专栏INFORMATION COLUMN

javascript垃圾收集知识点概要(三)

jayce / 2970人阅读

摘要:可是,引用计数导致的麻烦并未就此终结。其中,变量有一个名为的属性指向对象而变量也有一个属性名为回指。当垃圾收集器下次运行时,就会删除这些值并回收它们所占用的内存。

引用计数
  

另一种不太常见的垃圾收集策略叫做引用计数(reference counting)。引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个应用类型值赋给该变量时,则这个值的应用次数就是1。如果同一个值又被赋给另一个变量,这该值的引用次数加1。相反,如果包含对这个值引用的变量又取得了另外一个值,则该值的应用次数减1。当这个值的应用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其占用的内存空间回收回来。这样,当垃圾收集器下次再运行时,它就会释放那些引用次数为零的值所占用的内存。

Netscape Navigator3.0是最早使用引用计数策略的浏览器,但很快它就遇到了一个严重的问题:循环利用。循环利用指的是对象A中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。请看下面这个例子:

function problem(){
    var objectA = new Object();
    var objectB = new Object();

    objectA.someOtherObject = objectB;
    objectB.anotherObject = objectA;
}
  

在这个例子中,objectA和objectB通过各自的属性相互引用;也就是说,这两个对象的应用次数都是2.在采用标记清除策略的实现中,由于函数执行之后,这两个对象都离开了作用域,因此这种相互引用不是个问题。但在采用引用计数策略的实现中,当函数执行完毕之后,objectA和objectB还将继续存在,因为它们的应用次数永远不会是0.假如这个函数被重复调用,就会导致大量内存得不到回收。因此,Netscape在Navigator4.0中放弃了引用计数方式,转而采用了标记清除来实现其垃圾收集机制。可是,引用计数导致的麻烦并未就此终结。

我们知道,IE中有一部分对象并不是原生的JavaScript对象。例如,其BOM和DOM中的对象就是使用C++以COM(Component Object Model,组件对象模型)对象的形式实现的,而COM对象的垃圾收集机制采用的就是引用计数策略。因此,即使IE的JavaScript引擎是使用了标记清除策略来实现的,但JavaScript访问的COM对象依然是基于引用计数策略的。换句话说,只要在IE中涉及COM对象,就会在循环引用的问题。下面这个简单的例子,展示了使用COM对象导致循环引用的问题:

var element = document.getElementById("element");
var myObject = new Object();
myObject.elemnet = element;
element.someObject = myObject;
  

这个例子在一个DOM元素(element)与一个原生JavaScript对象之间创建了循环引用。其中,变量myObject有一个名为element的属性指向element对象;而变量elemnet也有一个属性名为someObject回指myObject。由于存在这个循环利用,即使将例子中的DOM从页面中删除,它也永远不会被回收。
为了避免类似这样的循环引用问题,最好是在不使用它们的时候手工断开原生JavaScript对象与DOM元素之间的连接。例如,可以使用下面的代码消除前面例子创建的循环引用:

myObject.element = null;
element.someObject = null;
  

将变量设置为null意味着切断变量与此前引用的值之间的连接。当垃圾收集器下次运行时,就会删除这些值并回收它们所占用的内存。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85325.html

相关文章

  • javascript垃圾收集识点概要(二)

    摘要:标记清除中最常用的垃圾收集方式是标记清除。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。到年为止,和的实现使用的都是标记清除式的垃圾收集策略或类似的策略,只不过垃圾收集的时间间隔互有不同。 标记清除 Javascript中最常用的垃圾收集方式是标记清除(mark-and-sweep)。当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量...

    TesterHome 评论0 收藏0
  • javascript垃圾收集识点概要(一)

    摘要:待分析下面我们来分析一下函数中局部变量的正常声明周期。局部变量只在函数执行的过程中存在。此时,局部变量就没有存在的必要了,因此可以释放他们的内存以供将来使用。 以下总结内容来自《JavaScript高级程序》(第三版) 页码:78 JavaScript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。而在C和C++之类的语言中,开发人员的一项基本任务就...

    Cheriselalala 评论0 收藏0
  • JavaScript如何工作:内存管理+如何处理4个常见的内存泄漏

    摘要:本系列的第一篇文章简单介绍了引擎运行时间和堆栈的调用。编译器将插入与操作系统交互的代码,并申请存储变量所需的堆栈字节数。当函数调用其他函数时,每个函数在调用堆栈时获得自己的块。因此,它不能为堆栈上的变量分配空间。 本系列的第一篇文章简单介绍了引擎、运行时间和堆栈的调用。第二篇文章研究了谷歌V8 JavaScript引擎的内部机制,并介绍了一些编写JavaScript代码的技巧。 在这第...

    anRui 评论0 收藏0
  • 《深入理解Java虚拟机》(六)堆内存使用分析,垃圾收集器 GC 日志解读

    摘要:堆内存使用分析,垃圾收集器日志解读重要的东东在中,对象实例都是在堆上创建。机制是由提供,用来清理需要清除的对象,回收堆内存。在中,是由一个被称为垃圾回收器的守护线程执行的。 堆内存使用分析,垃圾收集器 GC 日志解读 重要的东东 在Java中,对象实例都是在堆上创建。一些类信息,常量,静态变量等存储在方法区。堆和方法区都是线程共享的。 GC机制是由JVM提供,用来清理需要清除的对象,...

    CODING 评论0 收藏0
  • 【进阶1-4期】JavaScript深入之带你走进内存机制

    摘要:引擎对堆内存中的对象进行分代管理新生代存活周期较短的对象,如临时变量字符串等。内存泄漏对于持续运行的服务进程,必须及时释放不再用到的内存。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第一期,本周的主题是调用堆栈,今天是第4天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了解本进阶计划...

    不知名网友 评论0 收藏0

发表评论

0条评论

jayce

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<