javascript渣滓网络知识点提要(三)

援用计数

另一种不太罕见的渣滓网络战略叫做援用计数(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://segmentfault.com/a/1190000000700703
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞