垃圾收集

Javascript具有自动垃圾收集机制。

原理是:找到那些不在继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔(或代码执行中预定的收集时间),周期性执行这一操作。

垃圾收集策略有两种:

1.标记清除(make-and-sweep)

  1. 垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。

  2. 在此之后再被加上标记的变量将被视为准备删除的变量。

  3. 销毁带标记的值并回收它们所占用的内存空间。

现代浏览器都用这种垃圾回收策略。

2.引用计数

跟踪记录每个值被引用的次数。

  1. 当声明了一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数为1。
  2. 如果同一个值又被赋给另一个变量,则该值的引用次数再加1。
  3. 如果包含对这个值的引用变量取得了另外一个值,则这个值得引用次数减1。
  4. 当这个值得引用次数为0时,就可将其占用的内存空间回收。这样,当垃圾收集器下次再运行时,它会释放那些引用次数为0所占用的内存。

问题:如果循环引用,该对象无法被释放。

老的IE会用这个策略。

减少JavaScript中的垃圾回收

首先,最明显的,new关键字就意味着一次内存分配,例如 new Foo()。最好的处理方法是:在初始化的时候新建对象,然后在后续过程中尽量多的重用这些创建好的对象。

另外还有以下三种内存分配表达式(可能不像new关键字那么明显了):

  • {} (创建一个新对象)
  • [] (创建一个新数组)
  • function() {…} (创建一个新的方法,注意:新建方法也会导致垃圾收集!!)
1.对象object优化

为了最大限度的实现对象的重用,应该像避使用new语句一样避免使用{}来新建对象。

2.数组array优化

将[]赋值给一个数组对象,是清空数组的捷径(例如: arr = [];),但是这种方式又创建了一个新的空对象,并且将原来的数组对象变成了一小片内存垃圾!

建议:将数组长度赋值为0(arr.length = 0)不仅能达到清空数组的目的,并且同时能实现数组重用,减少内存垃圾的产生

3.方法function优化

只要是动态创建方法的地方,就有可能产生内存垃圾。尽量只创建一个函数对象,多次使用。

4. 删除带有事件处理的元素

从文档中删除带有事件处理程序的元素,如果没有手动删除该元素上的事件(addEventListener或者removeEventListener),那么原来添加到元素中的事件处理程序极有可能被当作垃圾回收(只是有可能)。参考如下例子:

<div id="myDiv"> 
    <input type="button" value="Click Me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
    var btn=document.getElementById("myBtn");  
    btn.onclick=function(){  
        document.getElementById("myDiv").innerHTML="Processing…";  
    }  
</script>

当按钮被从页面中移除时,它还带着一个事件处理程序,在

元素中设置innerHTML可以把按钮移走,但事件处理各种仍然与按钮保持着引用联系。 有的浏览器(尤其是IE)在这种情况下不会作出恰当的处理,它们很有可能会将对元素和事件处理程序的引用都保存在内存中。 如果你想知道某个元即将被移除,那么最好手工移除事件处理程序。

<div id="myDiv"> 
<input type="button" value="Click Me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
    var btn=document.getElementById("myBtn");  
    btn.onclick=function(){  
        btn.onclick=null;  
        document.getElementById("myDiv").innerHTML="Processing…";  
    }  
</script>

results matching ""

    No results matching ""