垃圾回收

    浏览器的垃圾回收机制会定期的运行,借以清理javascript运行过程中的内存垃圾。常见的垃圾回收策略有以下两种:

   1.标记清除

       垃圾回收例程先给内存中的变量打上标记,然后对于那些进入执行环境的变量清除掉他们的标记,再针对那些仍然拥有标记的变量进行回收。 

   2.引用计数

        当将一个引用类型的值赋值给某个变量的时候,该值的引用次数就加1。当包含对该值的引用的变量赋值为另外一个值,该值的引用次数就减1.当垃圾回收例程运行的时候会针对那些引用次数为0的对象进行回收,理由是这些对象不会再被访问到。


   内存泄露:

   1.IE中对于BOM和DOM的对象的实现方式是c++的COM对象的实现方式,因此也采用引用计数方式进行垃圾回收。

var input = document.getElementById("test");
var obj = {};
obj.input = input;
input.parent = obj;
    针对上面的例子,由于obj的input属性指向了Dom对象input,input的引用次数将为2(包括 input变量自身),则垃圾回收例程在回收的时候将不能回收input对象。即使离开当前执行环境也无法回收。obj这个变量虽然在离开当前执行环境会被回收,但是它所指向的引用对象将不会被回收。因为存在循环引用。
window.onload = function () {
            (function () {
                var input = document.getElementById("test");
                var obj = {};
                obj.input = input;
                input.parent = obj;
            })();
            alert(typeof input);//undefined
            alert(typeof obj);//undefined
            var input2 = document.getElementById("test");
            alert(typeof input2.parent)//object
}

基于以上情况,为了维护内存,建议在对象使用完以后将变量设置为null,解除引用,使得变量的值脱离当前执行环境,也可以使得Dom对象的引用计数变为0。

obj.input = null;
input.parent = null;

另外一种循环引用的写法:

function handler() {
    var input = document.getElementById("test");
    input.click = function () {
        alert(input.value);
    }
}

其中闭包函数的作用域链中有对于handler变量对象的引用,而input的click又指向该匿名函数,导致循环引用。input对象将无法回收,改下代码如下:

function handler() {
    var input = document.getElementById("test");
    var value = input.value;
    input.click = function () {
        alert(value);
    }
    input = null;//如果不设置input=null还是循环引用,设置为null才能保证闭包函数作用域链的变量对象对于input的引用消除
}

阅读更多
个人分类: Js基础知识
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭