JavaScript 垃圾回收

来源:互联网 发布:base64 js 源码 编辑:程序博客网 时间:2024/05/19 14:34

在 C 和 C++ 语言中,开发人员的一项基本任务就是手工跟踪内存的使用情况,并进行垃圾回收。而在编写  javascript  程序时,开发人员不在关心内存使用问题,所需内存的分配以及无用内存的回收完全实现了自动管理。这种垃圾回收机制的原理其实很简单:找出那些不再使用的变量,然后释放其占用的内存。为此,垃圾收集器会在按照图钉的时间间隔,周期性的执行一次垃圾收集操作。

  1.  标记清除
           JavaScript 中最常用的垃圾收集方式是标记清除(mark and sweep)。当变量进入环境时就在变量上标记 “进入环境” ,从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到他们。而当变量离开环境时,将其标记为 “ 离开环境 ”。
           可以使用任何方式来标记变量,如何标记变量其实并不重要,关键在于采取哪种策略。垃圾收集器在运行时会给存储在内存中的所有变量加上标记,他会去掉进入环境中的变量以及被环境中的变量引用的变量的标记。而在此之后被加上标记的变量会被视为准备删除的标量,原因是在环境中的变量已经无法访问到这些变量了,最后垃圾收集器在完成清除工作时,销毁那些带标记的标量并收回他们所占用的内存。
           到 2008 年,IE,fireFox,Opera,chrome,Safari 的 JavaScript 实现使用的都是标记清除式的回收策略,只不过垃圾收集的时间间隔有所不同。
  2. 引用计数
         另一种常见的垃圾回收策略叫做引用计数,引用计数的含义是跟踪每一个值被引用的次数。当声明了一个变量并将一个引用类型的值赋给该变量时,则这个变量的引用值为 1 ,如果同一个值又被赋给另一个变量,则该值的引用次数加 1 。相反,如果包含对这个值引用的变量又得到了另一个值,则这个值的引用次数减 1 ,当这个值的引用次数变为 0 时,则表示在没有办法访问这个值了,因此,就可以将这个值占用的内存空间回收回来,这样,垃圾收集器再次运行时,他就会释放那些引用次数为0  的值,所占用的空间。
         这种策略很快就遇到了一个严重的问题:循环引用,循环引用是指对象 A 中包含了一个指向对象 B 的指针,而对象 B 中又包含了一个指向 对象 A 的引用。看下面这个例子:
    function problem(){
        var objA = new Object(); 
        var objB = new Object(); 
        objA.someOtherObj = objB; 
        objB.anotherObj = objA; 
    }
    在这个例子中,objA 和 objB 通过各自的属性互相引用,也就是说,两个对象的引用次数都是2.在采用标记清除策略中,由于对象离开了作用域,因此这种互相引用不是问题。但在引用计数策略中,当函数执行完毕,objA 和 objB 还将继续存在,因为他们的引用次数永远是不会是0。假如这个函数被重复调用多次,就回导致大量的内存得不到回收。Netscape Navigator 3.0 是最早使用引用计数策略的浏览器,就因为这个原因,Netscape Navigator 4.0 放弃了引用计数方式,转而采用标记清除方式来实现其垃圾回收机制。

    跟多 JavaScript 知识请阅读 《JavaScript 高级程序设计(第三版)》

0 0
原创粉丝点击