JavaScript垃圾回收机制

JavaScript具有自动垃圾收集机制,执行环境会负责管理代码执行过程中的内存。
垃圾回收机制的原理:找出那些不在继续使用的变量,释放其占用的内存。因此,垃圾收集器会按照固定的时间间隔,周期性地执行这一操作。

局部变量的生存周期:
局部变量只在函数执行的过程中存在,而在这个过程中,会为局部变量在栈(或堆)内存上分配内存,以便存储它们的值,然后在函数中使用这些变量,直至函数执行结束。

标记无用变量的策略:
(1)标记清除
JavaScript中最常用的垃圾收集方式是标记清除。当变量进入环境时,就将这个变量标记为“进入环境”,当变量离开环境时,则将其标记为“离开环境”。

垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。在此之后再被加上标记的变量将被视为准备删除的变量,最后,垃圾收集器会回收它们所占的内存空间。

var a="global";     //全局变量

function getObject(){
    var a="local";  //局部变量
}

首先,所有的变量均加上标记,全局变量a进入全局环境后,标记清除,当离开全局环境后,再次加上标记,垃圾收集器回收a所占的内存。局部变量a进入getObject环境后,标记清除,当a离开环境时,再次加上标记,垃圾收集器回收a所占的内存。

(2)引用计数
跟踪记录每个值被引用的次数。

当声明一个变量并将一个引用类型值赋给该变量时,则这个值的引用次数就是1,如果同一个值又被赋给另一个变量,则该值的引用次数加1,以此类推。相反,如果包含这个值引用的变量又取得另外一个值,则这个值的引用次数减1,当这个值的引用次数为0时,则会被垃圾收集器回收。

function problem(){
    var objectA = new Object();
    var objectB = new Object();

    objectA.someOtherObject = objectB;
    objectB.someOtherObject = objectA;
}

上例中,objectA和objectB相互引用,即这两个对象的引用次数都是2,标记清除策略正常,但在引用计数策略中出现问题,即:当函数执行完毕后,ObjectA和ObjectB还将继续存在,因为他们的引用次数永远也不会是0,若该函数被重复多次调用,就会导致大量内存得不到回收。

性能问题
垃圾收集器是周期性运行的,而且如果为变量分配的内存数量是客观的,那么回收工作量也是相当大的。在这种情况下,确定垃圾收集的时间间隔是一个非常重要的问题。

事实上,在有的浏览器中可以触发垃圾收集过程,但不建议读者使用。在IE中,调用window.CollectGarbage()方法会立即执行垃圾收集,在Opera7及更高版本中,调用window.opera.collect()也会启动垃圾收集。

管理内存
分配给web浏览器的可用内存数量通常要比分配给桌面应用程序的少。优化内存占用的最佳方式:为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其设为null来释放其引用——解除引用。这一做法适用于大多数全局变量和局部变量。局部变量会在他们离开执行环境时自动被解除引用。

var obj = new Object();
obj.num = 10;

var temp = obj;
alert(temp.num);  //10

temp = null;  //解除引用
alert(temp.num);  //发生错误

解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

参考文献 《JavaScript高级程序设计(第三版)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值