Cross-Page Leaks
Cross-Page Leaks和下一節(jié)提到的Pseudo-Leaks在我看來(lái),就是IE的bug,雖然MS死皮賴臉不承認(rèn)
大家可以看看這段例子代碼:
<html> <head> <script language="JScript"> // 這個(gè)函數(shù)會(huì)引發(fā)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 ; } // 而這個(gè)函數(shù)不會(huì)引發(fā)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這兩段函數(shù)的唯一區(qū)別就在于他們的代碼的循序,從代碼上看,兩段代碼的邏輯都沒(méi)有錯(cuò)。
但LeakMemory卻會(huì)造成泄露。原因是LeakMemory()會(huì)先建立起parentDiv和childDiv之間的連接,這時(shí)候,為了讓 childDiv能夠獲知parentDiv的信息,因此IE需要先建立一個(gè)臨時(shí)的scope對(duì)象。而后parentDiv建立了和 hostElement對(duì)象的聯(lián)系,parentDiv和childDiv直接使用頁(yè)面document的scope?上У氖,IE不會(huì)釋放剛才那個(gè)臨時(shí)的scope對(duì)象的內(nèi)存空間,直到我們跳轉(zhuǎn)頁(yè)面,這塊空間才能被釋放。而CleanMemory函數(shù)不同,他先把parentDiv和 hostElement建立聯(lián)系,而后再把childDiv和parentDiv建立聯(lián)系,這個(gè)過(guò)程不需要單獨(dú)建立臨時(shí)的scope,只要直接使用頁(yè)面 document的scope就可以了, 所以也就不會(huì)造成內(nèi)存泄露了
詳細(xì)原因,大家可以看看http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp這篇文章。
IE 6中垃圾回收算法,就是從那些直接"in scope"的對(duì)象開(kāi)始進(jìn)行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
這個(gè)被稱為“秀逗泄露”真是恰當(dāng)啊^-^
看看這個(gè)例子:
<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(){}" ; // 看內(nèi)存會(huì)不斷增加 } } </script> </head> <body> <button onclick=" LeakMemory()"> Memory Leaking Insert </button> <script id="hostElement">function foo(){}</script> </body> </html>
MS是這么解釋的,這不是內(nèi)存泄漏。如果您創(chuàng)建了許多無(wú)法獲得也無(wú)法釋放的對(duì)象,那才是內(nèi)存泄漏。在這里,您將創(chuàng)建許多元素,Internet Explorer 需要保存它們以正確呈現(xiàn)頁(yè)面。Internet Explorer 并不知道您以后不會(huì)運(yùn)行操縱您剛剛創(chuàng)建的所有這些對(duì)象的腳本。當(dāng)頁(yè)面消失時(shí)(當(dāng)您瀏覽完,離開(kāi)瀏覽器時(shí))會(huì)釋放內(nèi)存。它不會(huì)泄漏。當(dāng)銷毀頁(yè)面時(shí),會(huì)中斷循環(huán)引用。
唉~~~
詳細(xì)原因,大家可以看看http://msdn.microsoft.com/library/default.asp?url=/library/en-us/IETechCol/dnwebgen/ie_leak_patterns.asp這篇文章。
其它一些瑣碎的注意點(diǎn):
- 變量定義一定要用var,否則隱式聲明出來(lái)的變量都是全局變量,不是局部變量;
- 全局變量沒(méi)用時(shí)記得要置null;
- 注意正確使用delete,刪除沒(méi)用的一些函數(shù)屬性;
- 注意正確使用try...cache,確保去處無(wú)效引用的代碼能被正確執(zhí)行;
- open出來(lái)的窗口即使close了,它的window對(duì)象還是存在的,要記得刪除引用;
- 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,原文已經(jīng)連不上了) 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的改進(jìn) http://erik.eae.net/archives/2006/04/26/23.23.02/ ==>ie 7的改進(jìn) 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
經(jīng)典論壇交流: http://bbs.blueidea.com/thread-2845985-1-1.html
本文鏈接:http://m.95time.cn/tech/web/2008/5679.asp
出處:藍(lán)色理想
責(zé)任編輯:bluehearts
上一頁(yè) 關(guān)于Javascript的內(nèi)存泄漏問(wèn)題 [3] 下一頁(yè)
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|