javascript 垃圾回收
javascript具有自动回收功能,即自动将无用的变量释放,以清理占用的内存。因此开发者不必管理内存分配和释放问题。基本原理:当执行环境进入时,会将所有变量标记为“进入环境”标识,执行环境离开时,将所有变量标记为”离开环境“,然后垃圾收集下次运行时,就会找所有变量标记为”离开环境“,再把它们清除掉。web浏览器会周期性相隔一段时间来运行垃圾收集,具体间隔时间因浏览器不同,也可以由开发者指定,如在IE下可以用window.CollectGarbage(),Opera 7以及更高版本用window.opera.collect()立即执行垃圾收集(不建议开发者去手工执行垃圾回收,因为如果垃圾收集调用太频繁,反而性能降低,浏览器已经有很好的策略对应什么时候去回收最适合)。
垃圾回收策略通常有2种:标记清除和引用计数。
1.标记清除:
标记清除原理:垃圾回收运行时,会将所有变量都加上标记,再次把这些标记了的变量进行搜索引有没被其他变量引用,如果有则清除此标记(表示不能被清理),如果没有则不管,再后将所有标记的变量进行清除内存(因为有引用的变量已经被取消标记了,剩下标记的变量是可以清除的)。现在大部分浏览器都是采用这种策略。
2.引用计数:
引用计数原理:一个变量被引用1次则在该变量的引用数+1,如果再被其他引用,则再+1;相反释放了引用则-1,没任何引用了,则会=0。这样,垃圾收集运行时,就会查找所有变量引用为0,然后清理掉。引用计数有一致使缺点,就是如果2个对象相互引用,则它们的引用数永远都不可能为0,则永远都不可能对这2个对象进行回收,代码如下:
var objectA = new Object();
var objectB = new Object();
objectA.temp = objectB;
objectB.temp = objectA;
正因为有此缺点,所以才被各大浏览器厂商抛弃。
IE浏览器虽然采用标记清除策略,但其内部的COM和BOM并不是用原生javascript实现,而是用C++的COM组件实现,关于这部分用的策略就是引用计数,代码如下:
var doc = document.getElementById("div1");
var obj = new Object();
obj.some = doc;
doc.element = obj;
对于此情况,我们可以用这个方法解决:
obj.some = null;
doc.element = null;
将互相引用的变量断开,这样各个对象变量引用就会-1。 不过IE9已经彻底重写了此机制,统一用标记清理。
管理内存:
javascript有着方便的自动垃圾回收机制,使得开发人员完全不必关注内存问题,但javascript与众多语言还是有点不同,其中一个最重要的原因是:在操作系统上给浏览器分配的可用内存通常会比桌面应用程序少,这是为了防止网页运行大量程序使得占用资源多,最终导致系统崩溃。所以作为开发者,能够做到越少用内存越好。最简单的办法就是:将确定不用的对象马上清掉。(这里马上清掉并不是鼓励手工去执行垃圾回收,而是手工做个标记让垃圾回收知道这是可以回收的)。
解除引用:通常采用解除引用的方式表示通知垃圾回收这是个可以回收的变量,代码如下:
function fun() {
return Object();
}
var o = fun();
o = null;
在o确定不用时,马上置为null,即将该变量解除引用,使期脱离执行环境。
浙公网安备 33010602011771号