IE8 內(nèi)存泄露(內(nèi)存一直增長(zhǎng) )的原因及解決辦法
最近開(kāi)發(fā)的時(shí)候?qū)?yè)面使用了定時(shí)的局部更新,結(jié)果在ie6,7和Firefox下,一切正常,而在ie8下過(guò)上幾個(gè)小時(shí)就瀏覽器就崩潰了,顯示是內(nèi)存溢出,我以為是代碼寫(xiě)的不好導(dǎo)致內(nèi)存泄露,但是ie6,7又正常,調(diào)查了一下,原來(lái)這是ie8的bug。
問(wèn)題點(diǎn)
在IE8中,生成特定Dom節(jié)點(diǎn)所占用的內(nèi)存是不會(huì)被釋放的,即使這些節(jié)點(diǎn)被刪除內(nèi)存也不會(huì)被釋放。
內(nèi)存泄露的節(jié)點(diǎn)類(lèi)型包括:form、button、input、select、textarea、a、img和objec
其他的大部分節(jié)點(diǎn)類(lèi)型是不會(huì)泄露的,例如:span、div、p、table等等。
此問(wèn)題只發(fā)生在IE8,其他瀏覽器不發(fā)生。
如果用戶(hù)按了F5,IE8會(huì)重新刷新頁(yè)面,首先它會(huì)unload window.top,這時(shí)候會(huì)釋放掉內(nèi)存。如果頁(yè)面是iframe,則unload此iframe,沒(méi)有任何反應(yīng)??雌饋?lái)只有window.top被 unload,內(nèi)存才會(huì)被釋放。
例子
例1
執(zhí)行下面的代碼,IE8就會(huì)泄露內(nèi)存。
function leak1() {
var node = document.getElementById("TO_AREA");
node.innerHTML = "<img />";
node.innerHTML = "";
node = null;
}
注意:
* 此例子添加了節(jié)點(diǎn),所以會(huì)泄露。
* 在中有個(gè)div,id為“TO_AREA”。
* 提醒一下,這里沒(méi)有閉包和循環(huán)引用。
例2
下面的代碼沒(méi)有使用innerHTML,但是還是會(huì)泄露
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,而且這里也沒(méi)有閉包和循環(huán)引用。
例3
這是最簡(jiǎn)單,最直接的例子:
function leak4() {
var node = document.createElement("IMG");
document.body.appendChild(node);
document.body.removeChild(node);
}
注意:
* 如果用span來(lái)代替img,就不會(huì)有泄露了。
這些例子只在IE8中泄露內(nèi)存,我在Windows XP, Windows Vista, Windows Server 2008, Windows Server 2008 R2和Windows 7 中的IE8都作了測(cè)試,而且使用了IE8中的IE7兼容模式和標(biāo)準(zhǔn)模式,每種情況下都會(huì)泄露。
測(cè)試頁(yè)面
關(guān)于泄露
內(nèi)存大小隨著時(shí)間的推移而增長(zhǎng),但這并不直接導(dǎo)致瀏覽器崩潰。瀏覽器使用的內(nèi)存好像是有上限的,它似乎會(huì)從某些內(nèi)部手段來(lái)限制DHTML使用的內(nèi)存。
內(nèi)存到達(dá)上限后,瀏覽器會(huì)自動(dòng)處理,例如彈出對(duì)話(huà)框,顯示內(nèi)存不足。
經(jīng)過(guò)自己測(cè)試發(fā)現(xiàn) IFrame同樣存在這個(gè)問(wèn)題(在IE8下)
補(bǔ)充:iframe內(nèi)存釋放
Ext 核心開(kāi)發(fā)人員Jack的回答是,TabPanelItem在關(guān)閉時(shí)并不會(huì)對(duì)自定義到tab中的元素做特殊處理,這部分工作必須在控件外來(lái)完成。另一方面, 相關(guān)資料稱(chēng)IE在iframe元素的回收方面存在著bug,在通常情況下應(yīng)該將該元素的src屬性值修改為”abort:blank”,并手工將其從 DOM樹(shù)上移除,然后把腳本中引用它的變量置空并調(diào)用CollectGarbage()就可以避免iframe不能正常回收所造成的內(nèi)存泄露。
<script>
function clearRAM() {
var frame = document.getElementById("ifr_content");
frame.src = 'about:blank';
frame.contentWindow.document.write( '');//清空f(shuō)rame的內(nèi)容
frame.contentWindow.document.clear();
frame.contentWindow.close(); //避免frame內(nèi)存泄漏
if (navigator.userAgent.indexOf('MSIE') >= 0) {
if (CollectGarbage) {
CollectGarbage(); //IE 特有 釋放內(nèi)存
//刪除原有標(biāo)記
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);
}
}
}
//主動(dòng)釋放 5秒一次
setInterval( function() {
if (navigator.userAgent.indexOf('MSIE') >= 0) {
if (CollectGarbage) {
//alert(1)
CollectGarbage(); //IE 特有 釋放內(nèi)存
}
}
}, 5000)
</ script>
相關(guān)文章
JavaScript中document.querySelector函數(shù)用法介紹
這篇文章主要給大家介紹了關(guān)于JavaScript中document.querySelector函數(shù)用法的相關(guān)資料,document.querySelector是JavaScript中的一個(gè)內(nèi)置方法,用于通過(guò)CSS選擇器選擇文檔中的第一個(gè)匹配元素,需要的朋友可以參考下2023-08-08
微信小程序開(kāi)發(fā)之點(diǎn)擊按鈕退出小程序的實(shí)現(xiàn)方法
這篇文章主要介紹了微信小程序開(kāi)發(fā)之點(diǎn)擊按鈕退出小程序的實(shí)現(xiàn)方法,本恩通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-04-04
微信小程序點(diǎn)擊頂部導(dǎo)航欄切換樣式代碼實(shí)例
這篇文章主要介紹了微信小程序點(diǎn)擊頂部導(dǎo)航欄切換樣式代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
JS實(shí)現(xiàn)單個(gè)或多個(gè)文件批量下載的方法詳解
在前端Web開(kāi)發(fā)中,下載文件是一個(gè)很常見(jiàn)的需求。這篇文章就來(lái)和大家介紹下幾種download解決方案,以及特殊Case的最佳方案選擇,希望對(duì)大家有所幫助2023-02-02

