文档介绍:该【Js内存泄漏及解决方案 】是由【碎碎念的折木】上传分享,文档一共【19】页,该文档可以免费在线阅读,需要了解更多关于【Js内存泄漏及解决方案 】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文档到您的设备,方便您编辑和打印。JS内存泄露
10
在IE下的JS编程中,以下的编程方式都会造成即使关闭IE也无法释放内存的问题,下面分类给出:
1、给DOM对象添加的属性是一个对象的引用。范例:varMyObject={};
(”myDiv”).myProp=MyObject;
解决方法:
:(”myDiv”).myProp
=null;
2、DOM对象与JS对象相互引用。范例:functionEncapsulator(element){=element;=this;
}
newEncapsulator((”myDiv”));
解决方法:
在onunload大事中写上:(”myDiv”).myProp=null;
3、给DOM对象用attachEvent绑定大事。范例:functiondoClick{}(“onclick“,doClick);
解决方法:
在onunload大事中写上:(”onclick”,doClick);
4、从外到内执行appendChild。这时即使调用removeChild也无法释放。范例:
varparentDiv=(“div“);varchildDiv=(“div“);(parentDiv);(childDiv);
解决方法:
从内到外执行appendChild:
varparentDiv=(“div“);varchildDiv=(“div“);
JS内存泄露
10
(childDiv);
(parentDiv);
5、反复重写同一个属性会造成内存大量占用(但关闭IE后内存会被释放)。范例:
for(i=0;i<5000;i++){=“asdfasdfasdf“;
}
这种方式相当于定义了5000个属性!解决方法:
其实没什么解决方法:P~~~就是编程的时候尽量避开消灭这种状况咯~~
说明:
1、以上资料均来源于微软官方的MSDN站点,链接地址:
://...
大家可以到上面这个地址中看到具体的说明,包括范例和图例都有。只是我英文不太好,看不太懂,假设我上述有失误或有需要补充的地方请大家指出。
2、对于第一条,=funcRef这种写法也算在其中,由于这也是一个对对象的引用。在页面onunload时应当释放掉。
3、对于第三条,在MSDN的英文说明中似乎是说即使调用detachEvent也无法释放内存,由于在attachEvent的时候就已经造成内存“LEAK”了,不过detachEvent后状况还是会好一点。不知道是不是这样,请英文好的亲能够指出。
4、在实际编程中,这些内存问题的实际影响并不大,尤其是给客户使用时,客户对此绝不会有觉察,然而这些问题对于程序员来说却始终是个心病---有这样的BUG心里总会觉得不舒适吧?能解决则给与解决,这样是最好的。,在它们的源码里都会看到承受上述解决方式进展内存的释放治理。
理解并解决IE的内存泄漏方式
Web开发的进展
在过去一些的时候,Web开发人员并没有太多的去关注内存泄露问题。那时的页面间联系大都比较简洁,并主要使用不同的连接地址在同一
个站点中导航,这样的设计方式是格外有利于扫瞄器释放资源的。即使Web页面运行中真的消灭了资源泄漏,那它的影响也是格外有限而且常常
JS内存泄露
10
是不会被人在意的。
今日人们对Web应用有了高更的要求。一个页面很可能数小时不会发生URL跳转,并同时通过Web效劳动态的更页面内容。简单的大事关联
设计、基于对象的JScript和DHTML技术的广泛承受,使得代码的力量到达了其承受的极限。在这样的状况和转变下,弄清楚内存泄露方式变得
格外的急迫,特别是过去这些问题都被传统的页面导航方法给屏蔽了。
还算好的事情是,当你明确了期望查找什么时,内存泄露方式是比较简洁被确定的。大多数你能遇到的泄露问题我们都已经知道,你只需
要少量额外的工作就会给你带来好处。虽然在一些页面中少量的小泄漏问题仍会发生,但是主要的问题还是很简洁解决的。
泄露方式
在接下来的内容中,我们会争论内存泄露方式,并为每种方式给出例如。其中一个重要的例如是JScript中的Closure技术,另一个例如是
在大事执行中使用Closures。当你生疏本例如后,你就能找出并修改你已有的大多数内存泄漏问题,但是其它Closure相关的问题可能又会被忽
视。
现在让我们来看看这些个方式都有什么:
1、循环引用(CircularReferences)—IE扫瞄器的COM组件产生的对象实例和网页脚本引擎产生的对象实例相互引用,就会造成内存泄漏。
这也是Web页面中我们遇到的最常见和主要的泄漏方式;
2、内部函数引用(Closures)—Closures可以看成是目前引起大量问题的循环应用的一种特别形式。由于依靠指定的关键字和语法构造,
Closures调用是比较简洁被我们觉察的;
3、页面穿插泄漏(Cross-Leaks)—页面穿插泄漏其实是一种较小的泄漏,它通常在你扫瞄过程中,由于内部对象薄计引起。下面我们
JS内存泄露
10
会争论DOM插入挨次的问题,在那个例如中你会觉察只需要改动少量的代码,我们就可以避开对象薄计对对象构建带来的影响;
4、貌似泄漏(Pseudo-Leaks)—这个不是真正的意义上的泄漏,不过假设你不了解它,你可能会在你的可用内存资源变得越来越少的时候极
度郁闷。为了演示这个问题,我们将通过重写Script元素中的内容来引发大量内存的“泄漏“。
循环引用
循环引用根本上是全部泄漏的始作俑者。通常状况下,脚本引擎通过垃圾收集器
(GC)来处理循环引用,但是某些未知因数可能会阻碍从其
环境中释放资源。对于IE来说,某些DOM对象实例的状态是脚本无法得知的。下面是它们的根本原则:
JS内存泄露
10
Figure1:根本的循环引用模型
本模型中引起的泄漏问题基于COM的引用计数。脚本引擎对象会维持对DOM对象的引用,并在清理和释放DOM对象指针前等待全部引用的移除
。在我们的例如中,我们的脚本引擎对象上有两个引用:脚本引擎作用域和DOM对象的expando属性。当终止脚本引擎时第一个引用会释放,DOM
对象引用由于在等待脚本擎的释放而并不会被释放。你可能会认为检测并修复假设的这类问题会格外的简洁,但事实上这样根本的的例如只是
冰山一角。你可能会在30个对象链的末尾发生循环引用,这样的问题排查起来将会是一场噩梦。
假设你仍不清楚这种泄漏方式在HTML代码里到底怎样,你可以通过一个全局脚本变量和一个DOM对象来引发并呈现它。
<html>
<head>
<scriptlanguage=“JScript“>varmyGlobalObject;functionSetupLeak
{
//FirstsetupthescriptscopetoelementreferencemyGlobalObject=(“LeakedDiv“);
//(“LeakedDiv“).expandoProperty=myGlobalObject;
}
functionBreakLeak
{
(“LeakedDiv“).expandoProperty=null;
}
</script>
</head>
<bodyonload=“SetupLeak“onunload=“BreakLeak“>
<divid=“LeakedDiv“></div>
</body>
JS内存泄露
10
</html>
JS内存泄露
10
你可以使用直接赋null值得方式来破坏该泄漏情形。在页面文档卸载前赋null值,将会让脚本引擎知道对象间的引用链没
有了。现在它将能正常的清理引用并释放DOM对象。在这个例如中,作为Web开发员的你因该更多的了解了对象间的关系。
作为一个根本的情形,循环引用可能还有更多不同的简单表现。对基于对象的JScript,一个通常用法是通过封装JScript对象来扩大DOM对
象。在构建过程中,你常常会把DOM对象的引用放入JScript对象中,同时在DOM对象中也存放上对近创立的JScript对象的引用。你的这种应
用模式将格外便于两个对象之间的相互访问。这是一个格外直接的循环引用问题,但是由于使用不用的语法形式可能并不会让你在意。要破环
这种使用情景可能变得更加简单,固然你同样可以使用简洁的例如以便于清楚的争论。
<html>
<head>
<scriptlanguage=“JScript“>
functionEncapsulator(element)
{
//=element;
//=this;
}
functionSetupLeak
{
//Theleakhappensallatonce
newEncapsulator((“LeakedDiv“));
}
functionBreakLeak
{
(“LeakedDiv“).expandoProperty=null;
}
</script>
</head>
<bodyonload=“SetupLeak“onunload=“BreakLeak“>
<divid=“LeakedDiv“></div>
</body>
JS内存泄露
10
</html>
更简单的方法还有记录全部需要解除引用的对象和属性,然后在Web文档卸载的
时候统一清理,但大多数时候你可能会再造
成额外的泄漏情形,而并没有解决你的问题。
闭包函数(Closures)
由于闭包函数会使程序员在不知不觉中创立出循环引用,所以它对资源泄漏常常有着不行推卸的责任。而在闭包函数自己被释放前,我们很难推断父函数的参数以及它的局部变量是否能被释放。实际上闭包函数的使用已经很一般,以致人们频繁的遇到这类问题时我们却束手无策。在具体了解了闭包背后的问题和一些特别的闭包泄漏例如后,我们将结合循环引用的图示找到闭包的所在,并找出这些
不受欢送的引用来至何处。
JS内存泄露
10
JS内存泄露
10