首頁 > web前端 > js教程 > IE8 記憶體外洩(記憶體一直成長 )的原因及解決方法_javascript技巧

IE8 記憶體外洩(記憶體一直成長 )的原因及解決方法_javascript技巧

WBOY
發布: 2016-05-16 15:06:25
原創
1752 人瀏覽過

最近開發的時候對頁面使用了定時的局部更新,結果在ie6,7和Firefox下,一切正常,而在ie8下過上幾個小時就瀏覽器就崩潰了,顯示是內存溢出,我以為是程式碼寫的不好導致記憶體洩露,但ie6,7又正常,調查了一下,原來這是ie8的bug。

問題點

在IE8中,產生特定Dom節點所佔用的記憶體是不會被釋放的,即使這些節點被刪除記憶體也不會被釋放。

記憶體外洩的節點類型包括:form、button、input、select、textarea、a、img和objec

其他的大部分節點類型是不會洩漏的,例如:span、div、p、table等等。

此問題只發生在IE8,其他瀏覽器不發生。

如果使用者按了F5,IE8會重新刷新頁面,首先它會unload window.top,這時候會釋放掉記憶體。如果頁面是iframe,則unload此iframe,沒有任何反應。看起來只有window.top被 unload,記憶體才會被釋放。

範例

例1

執行下面的程式碼,IE8就會洩漏記憶體。

function leak1() { 
var node = document.getElementById("TO_AREA"); 
node.innerHTML = "<img />"; 
node.innerHTML = ""; 
node = null; 
} 
登入後複製

注意:

* 此範例新增了節點,所以會洩漏。

* 在中有個div,id為「TO_AREA」。

* 提醒一下,這裡沒有閉包和循環引用。

例2

下面的程式碼沒有使用innerHTML,但還是會洩漏

function leak2() { 
var node = document.getElementById("FROM_AREA").cloneNode(true); 
node.id = "NEW_AREA"; 
document.body.appendChild(node); 
document.body.removeChild(node); 
node = null; 
}
登入後複製

注意:

* FROM_AREA 是form的id,而且這裡也沒有閉包和循環引用。

例3

這是最簡單,最直接的例子:

function leak4() { 
var node = document.createElement("IMG"); 
document.body.appendChild(node); 
document.body.removeChild(node); 
}
登入後複製

注意:

* 如果用span來代替img,就不會有洩漏了。

這些範例只在IE8中洩漏內存,我在Windows XP, Windows Vista, Windows Server 2008, Windows Server 2008 R2和Windows 7 中的IE8都作了測試,而且使用了IE8中的IE7相容模式和標準模式,每種情況下都會洩漏。

測試頁

關於洩漏

記憶體大小隨著時間的推移而增長,但這並不直接導​​致瀏覽器崩潰。瀏覽器使用的記憶體好像是有上限的,它似乎會從某些內部手段來限制DHTML所使用的記憶體。

記憶體到達上限後,瀏覽器會自動處理,例如彈出對話框,顯示記憶體不足。

經過自己測試發現 IFrame同樣存在這個問題(在IE8下)

補充:iframe記憶體釋放

Ext 核心開發人員Jack的回答是,TabPanelItem在關閉時並不會對自訂到tab中的元素做特殊處理,這部分工作必須在控制項外來完成。另一方面, 相關資料稱IE在iframe元素的回收方面存在bug,在通常情況下應該將該元素的src屬性值修改為”abort:blank”,並手工將其從DOM樹上移除,然後把腳本中引用它的變數置空並呼叫CollectGarbage()就可以避免iframe不能正常回收所造成的記憶體外洩。

<script>
function clearRAM() {
var frame = document.getElementById("ifr_content");
frame.src = 'about:blank';
frame.contentWindow.document.write( '');//清空frame的内容
frame.contentWindow.document.clear();
frame.contentWindow.close(); //避免frame内存泄漏
if (navigator.userAgent.indexOf('MSIE') >= 0) {
if (CollectGarbage) {
CollectGarbage(); //IE 特有 释放内存
//删除原有标记
var tags = document.getElementById("ifrSet");
tags.removeChild(frame);
//添加frameset框架
var _frame = document.createElement('frame');
_frame.src = '';
_frame.name = 'content';
_frame.id = 'ifr_content';
tags.appendChild(_frame);
}
}
}
//主动释放 5秒一次
setInterval( function() {
if (navigator.userAgent.indexOf('MSIE') >= 0) {
if (CollectGarbage) {
//alert(1)
CollectGarbage(); //IE 特有 释放内存
}
}
}, 5000) 
</ script>
登入後複製
相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板