Cross-Page Leaks
Cross-Page Leaks和下一节提到的Pseudo-Leaks在我看来,就是IE的bug,虽然MS死皮赖脸不承认
大家可以看看这段例子代码:
<html> <head> <script language="JScript"> // 这个函数会引发Cross-Page Leaks function LeakMemory() { var hostElement=document.getElementById("hostElement"); // Do it a lot, look at Task Manager for memory response for (i=0 ;i<5000;i++){ var parentDiv = document.createElement("<div onClick='foo()'>"); var childDiv = document.createElement("<div onClick='foo()'>"); // This will leak a temporary object parentDiv.appendChild(childDiv); hostElement.appendChild(parentDiv); hostElement.removeChild(parentDiv); parentDiv.removeChild(childDiv); parentDiv = null ; childDiv = null ; } hostElement = null ; } // 而这个函数不会引发Cross-Page Leaks function CleanMemory() { var hostElement = document.getElementById("hostElement"); // Do it a lot, look at Task Manager for memory response for (i=0;i<5000;i++) { var parentDiv = document.createElement("<div onClick='foo()'>"); var childDiv = document.createElement("<div onClick='foo()'>"); // Changing the order is important, this won't leak hostElement.appendChild(parentDiv); parentDiv.appendChild(childDiv); hostElement.removeChild(parentDiv); parentDiv.removeChild(childDiv); parentDiv = null ; childDiv = null ; } hostElement = null ; } </script> </head> <body> <button onclick="LeakMemory()"> Memory Leaking Insert </button> <button onclick="CleanMemory()" > Clean Insert </button> <div id="hostElement"></ div > </body> </html>
LeakMemory和CleanMemory这两段函数的唯一区别就在于他们的代码的循序,从代码上看,两段代码的逻辑都没有错。
但LeakMemory却会造成泄露。原因是LeakMemory()会先建立起parentDiv和childDiv之间的连接,这时候,为了让 childDiv能够获知parentDiv的信息,因此IE需要先建立一个临时的scope对象。而后parentDiv建立了和 hostElement对象的联系,parentDiv和childDiv直接使用页面document的scope。可惜的是,IE不会释放刚才那个临时的scope对象的内存空间,直到我们跳转页面,这块空间才能被释放。而CleanMemory函数不同,他先把parentDiv和 hostElement建立联系,而后再把childDiv和parentDiv建立联系,这个过程不需要单独建立临时的scope,只要直接使用页面 document的scope就可以了, 所以也就不会造成内存泄露了
详细原因,大家可以看看http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp这篇文章。
IE 6中垃圾回收算法,就是从那些直接"in scope"的对象开始进行mark清除的:
Every variable which is "in scope" is called a "scavenger". A scavenger may refer to a number, an object, a string, whatever. We maintain a list of scavengers – variables are moved on to the scav list when they come into scope and off the scav list when they go out of scope.
Pseudo-Leaks
这个被称为“秀逗泄露”真是恰当啊^-^
看看这个例子:
<html> <head> <script language="JScript"> function LeakMemory() { // Do it a lot, look at Task Manager for memory response for (i=0;i<5000;i++) { hostElement.text = "function foo(){}" ; // 看内存会不断增加 } } </script> </head> <body> <button onclick=" LeakMemory()"> Memory Leaking Insert </button> <script id="hostElement">function foo(){}</script> </body> </html>
MS是这么解释的,这不是内存泄漏。如果您创建了许多无法获得也无法释放的对象,那才是内存泄漏。在这里,您将创建许多元素,Internet Explorer 需要保存它们以正确呈现页面。Internet Explorer 并不知道您以后不会运行操纵您刚刚创建的所有这些对象的脚本。当页面消失时(当您浏览完,离开浏览器时)会释放内存。它不会泄漏。当销毁页面时,会中断循环引用。
唉~~~
详细原因,大家可以看看http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp这篇文章。
其它一些琐碎的注意点:
- 变量定义一定要用var,否则隐式声明出来的变量都是全局变量,不是局部变量;
- 全局变量没用时记得要置null;
- 注意正确使用delete,删除没用的一些函数属性;
- 注意正确使用try...cache,确保去处无效引用的代码能被正确执行;
- open出来的窗口即使close了,它的window对象还是存在的,要记得删除引用;
- frame和iframe的情况和窗口的情况类似。
考资料参:
http://jibbering.com/faq/faq_notes/closures.html http://javascript.weblogsinc.com/2005/03/07/javascript-memory-leaks/ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp http://72.14.203.104/search?q=cache:V9Bt4_HBzQ8J:jgwebber.blogspot.com/2005/01/dhtml-leaks-like-sieve.html+DHTML+Leaks+Like+a+Sieve+&hl=zh-CN&ct=clnk&cd=9 (这是DHTML Leaks Like a Sieve)一文在google上的cache,原文已经连不上了) http://spaces.msn.com/siteexperts/Blog/cns!1pNcL8JwTfkkjv4gg6LkVCpw!338.entry http://support.microsoft.com/default.aspx?scid=KB;EN-US;830555 http://www.ajaxtopics.com/leakpatterns.html http://blogs.msdn.com/ericlippert/archive/2003/09/17/53028.aspx http://www.quirksmode.org/blog/archives/2005/02/javascript_memo.html http://youngpup.net/2005/0221010713 http://blogs.msdn.com/ericlippert/archive/2003/09/17/53038.aspx = http://support.microsoft.com/kb/266071/EN-US ==>IE 5.0至5.5一些版本中的GC bug http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html ==>ie 7的改进 http://erik.eae.net/archives/2006/04/26/23.23.02/ ==>ie 7的改进 http://www.feedbackarchive.com/spamvampire/today.html ==> Try this script for memory leaks - it leaked 50 megabytes in 15 minutes with firefox on linux: http://birdshome.cnblogs.com/archive/2005/02/15/104599.html http://www.quirksmode.org/dom/innerhtml.html http://www.crockford.com/javascript/memory/leak.html 《JavaScript: The Definitive Guide》4th Edition http://outofhanwell.com/ieleak/index.php?title=Main_Page
经典论坛交流: http://bbs.blueidea.com/thread-2845985-1-1.html
本文链接:http://www.blueidea.com/tech/web/2008/5679.asp
出处:蓝色理想
责任编辑:bluehearts
上一页 关于Javascript的内存泄漏问题 [3] 下一页
◎进入论坛网页制作、WEB标准化版块参加讨论,我还想发表评论。
|