[转载]JavaSCRIPT 内存泄露

当一个系统不能正确的管理它的内存分配,就称之为内存泄露,这是一种BUG,其症状包括执行效率的降低和程序运行失败。
IE包含大量的泄露,最坏的一种发生在与JSCRIPT的交互过程中。当一个DOM对象包含了一个指向JS对象的引用(例如一个事件处理函数),而该JS对象也同时包含该DOM对象的引用时,一个循环结构形成了,在JS里这并不是一个问题,在这种情况下如果没有其他的引用指向这个DOM对象和事件处理句柄,垃圾回收器(一种自动管理内存的装置)将回收他们。而不幸的是,当一个死循环发生时,内存回收就不会发生了,因此发生内存泄露,随着时间的推移,内存被耗尽,内存空间充满正在使用的CELL时,浏览器就就挂起了。

 

我们可以举个例子,在一个程序(queuetest1)中,我们不停的创建10000个DOM元素,与此同时,删除掉除了最近创建的10个元素外的所有元素,当你打开任务管理器查看时,你将会看到PF(page file,即页面文件)的使用率任然保持在一个几乎恒定的水平上。PF使用率的改变可以作为内存分配无效的标志(原文:Changes on PF Usage can be an indicator of memory allocation inefficiency.)。

随后,我们运行第二个程序,queuetest2,它和第一个程序做的事情几乎相同,但不同的是他为每个元素增加了一个单击事件的处理器(click handler),在Mozilla和Opera中,PF使用率几乎保持不变,而在IE中,我们可以看到因为内存的泄露而引起的PF使用率以MB/S的速度稳步增长,通常情况下这种内存泄露经常被忽视。但是随着AJAX技术变得越来越流行,造成一张页面在浏览器中停留的时间也就越长,这种情况下对同一张页面操作的增加,就更有可能造成失败。

因为IE在回收循环上的失败,这幅担子不可避免的落到了我们头上,如果我们显式的破坏循环,IE就可以成功的回收内存了。但是根据 Microsoft官方的观点,闭包(closure)是引起内存泄露(memory leaks)的元凶,这当然是极端错误的观点。由此看来,在有关如何处理微软BUG方面,微软提供了非常坏的建议。事实证明了我们可以很容易的在DOM这一边上破坏循环,从而解决问题,而不大可能在JSCRIPT的那一端把死循环破坏掉。

因此,可以这样来解决上述问题:
我们在完成一个元素的操作后,必须将元素的事件处理器置空以便退出可能存在的死循环,我们可以将元素的事件处理器属性赋值为NULL来解决这个问题。这可以作为一个规范来完成,或者我们写一个通用的purge函数来完成这一任务。

purge函数可以接受一个DOM元素作为它的参数。它对元素的各个属性进行循环比较,将任何值为函数的属性置为null,这样就退出了可能存在的死循环,允许占用的资源被回收。purge函数也将检查元素的后代元素,并同样破坏它们所有可能的死循环。当然,专门为IE浏览器处理内存回收BUG而定制的purge函数运行在Mozilla和Opera上是无害的。要注意的是,应当在移除元素、移除子元素,和设定该元素的innerHTML之前调用 purge函数。

下面给出purge函数的代码:
function purge(d) {
var a = d.attributes, i, l, n;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
n = a[i].name;
if (typeof d[n] === 'function') {
d[n] = null;
}
}
}
a = d.childNodes;
if (a) {
l = a.length;
for (i = 0; i < l; i += 1) {
purge(d.childNodes[i]);
}
}
}

我们在IE上运行第三个程序queuetest3,在queuetest3中,移除DOM元素之前purge函数将会被调用。
----------------------------------------------------------------------------------------------------
update:微软宣称已经修复了这个代号为929874的问题,如果你确信你所有的用户都对微软的这个BUG修复感到满意,那么你可以不在你的程序中调用purge函数。而不幸的是,至今我们还不能作出定论,所以建议在IE6上的程序中仍然使用purge函数。

这就是web的特点,修补一个bug并不一定代表bug就再也不会存在。

 

转载自:http://topic.csdn.net/u/20080704/18/236b4ee8-8fab-4325-b3e9-43253bc3308e.html?775954648

posted @ 2010-09-09 10:19  Timo队长  阅读(394)  评论(0编辑  收藏  举报