ECMAScript垃圾回收机制及性能提升

来源:互联网 发布:坏坏的女人有魅力知乎 编辑:程序博客网 时间:2024/06/05 18:39

ECMAScript的垃圾回收主要有两种算法,一种是引用计数,一种是标记清除;

引用计数

引用计数的主要思想是为内存中的每个对象保持一个计数器,如果一个对象的引用次数为0,那么这样的对象就可以作为垃圾回收了。例如:A、B都是Obj对象的引用,那么Obj的引用计数为2,如果某函数调用返回后,A的生命周期结束,那么Obj的引用计数就为1,如果Obj的引用次数变为0,那么它就可以回收了。

这种方式的缺点就是如果两个对象互相引用,就无法回收这两个对象了,即使以后再也不会使用这两个对象,他们也会占用内存。

标记清除

标记清除的主要思想是先建立各个对象的关联,然后从根节点出发,使用广度优先搜索依次标记所有对象,那些不能被标记的对象就应该作为垃圾回收。

这种方式的主要缺点就是如果某些对象被清理后,内存是不连续的,那么就算内存占用率不高,例如只有50%,但是由于内存空隙太多,后来的大对象甚至无法存储到内存之中。

对于这种垃圾回收方式的缺点,一般的处理方式都是在垃圾回收后进行整理操作,这种方法也叫标记整理,整理的过程就是将不连续的内存向一端复制,使不连续的内存连续起来。

现在ie,chrome,firefox,opera及safari都是采用标记清除的垃圾收集策略。ie8及之前的BOM,COM接口都不是原生的JavaScript对象,它们是使用C++以COM对象的形式实现的,而COM的对象的垃圾收集机制采用的就是引用计数策略。因此,对于ie8浏览器,为了避免循环引用导致对象不被垃圾收集器收集情况的出现。建议在不适用它们的时候将对象置为null,如下示例:

var aObj = document.getElementById("a_id");var bObj = new Object();bObj.aElement = aObj;aObj.bElement = bObj;...aObj = null;bObj = null;
将变量重置为null,意味着切断了变量与此前引用的值之间的连接。当垃圾收集器下次运行时,就会删除这些值并回收它们占用的内存。

性能提升 

系统分配给浏览器的内存要比桌面应用程序的少。这么做是出于安全方面的考虑,目的是防止运行JavaScript的网页耗尽系统内存而导致系统崩溃。
对于局部变量来说,当退出当前作用域时,给局部变量分配的内存就会被回收。但是,对于全局变量,当我们不用时。则需要手动解除它的引用,以便垃圾收集器下次运行时回收其内存。
function test(name){    var localVar = new Object();    localVar.name = name;    return localVar;}var globalVar = test("jack");// 手工解除globalVar的引用globalVar = null;
最后,对于全局对象、全局对象属性以及循环引用变量的引用,应该及时清除。

0 0
原创粉丝点击