渣滓接纳机制——总结自《JavaScript高等程序设计》

渣滓网络(garbage collection)

在编写 JavaScript 程序时,开发人员不必再体贴内存运用题目,所需内存的分派以及无用内存的接纳完整完成了自动治理。这类渣滓网络机制的道理实在很简单:找出那些不再继承运用的变量,然后开释其占用的内存。为此,渣滓网络器会根据牢固的时刻距离(或代码实行中预定的网络时刻),周期性地实行这一操纵。

渣滓网络器必需跟踪哪一个变量有效哪一个变量没用,关于不再有效的变量打上标记,以备未来收回其占用的内存。用于标识无用变量的战略可能会因完成而异,但详细到浏览器中的完成,则一般有两个战略:标记消灭和援用计数

标记消灭(mark-and-sweep)

渣滓网络器在运转的时刻会给存储在内存中的一切变量都加上标记(固然,能够运用任何标记体式格局)。然后,它会去掉环境中的变量以及被环境中的变量援用的变量的标记。而在此之后再被加上标记的变量将被视为预备删除的变量,缘由是环境中的变量已无法接见到这些变量了。末了,渣滓网络器完成内存消灭事情,烧毁那些带标记的值并接纳它们所占用的内存空间。

到 2008 年为止, IE、 Firefox、 Opera、 Chrome 和 Safari 的 JavaScript 完成运用的都是标记消灭式的渣滓网络战略(或相似的战略),只不过渣滓网络的时刻距离互有差别。

援用计数(reference counting)

当声清楚明了一个变量并将一个援用范例值赋给该变量时,则这个值的援用次数就是 1。如果同一个值又被赋给另一个变量,则该值的援用次数加 1。相反,如果包括对这个值援用的变量又取得了别的一个值,则这个值的援用次数减 1。当这个值的援用次数变成 0 时,则申明没有办法再接见这个值了,因而就能够将其占用的内存空间接纳返来。如许,当渣滓网络器下次再运转时,它就会开释那些援用次数为零的值所占用的内存。

但在采纳援用计数战略的完成中,当函数实行终了后,函数内部轮回援用的对象还将继承存在,因为它们的援用次数永久不会是 0。如果这个函数被反复屡次挪用,就会致使大批内存得不到接纳。恰是因为这个缘由,Netscape在Navigator 4.0中摒弃了援用计数体式格局,转而采纳渣滓接纳。

//轮回援用实例
function problem(){
var objectA = new Object();
var objectB = new Object();
objectA.someOtherObject = objectB;
objectB.anotherObject = objectA;
}

IE 中有一部分对象并非原生 JavaScript 对象。比方,其 BOM 和 DOM 中的对象就是运用 C++以 COM(Component Object Model,组件对象模子)对象的情势完成的,而 COM 对象的渣滓网络机制采纳的就是援用计数战略。因而,纵然 IE 的 JavaScript 引擎是运用标记消灭战略来完成的,但JavaScript 接见的 COM 对象依然是基于援用计数战略的。换句话说,只要在 IE 中触及 COM 对象,就会存在轮回援用的题目。为了防止相似如许的轮回援用题目,最好是在不运用它们的时刻手工断开原生 JavaScript 对象与DOM 元素之间的衔接(赋值为null)。
IE9 把 BOM 和 DOM 对象都转换成了真正的 JavaScript 对象。如许,就防止了两种渣滓网络算法并存致使的题目,也消除了罕见的内存走漏征象。

总结:内存的自动接纳基于两种战略:个中的援用计数战略在对象轮回援用时不可用,IE8及以下的DOM和BOM对象操纵深受其害;现在,IE9+和其他四大浏览器基础支撑标记消灭体式格局,区分仅在于渣滓接纳的周期差别。

    原文作者:zhangding
    原文地址: https://segmentfault.com/a/1190000007013594
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞