Javascript 閉包引起的IE記憶體泄露分析

來源:互聯網
上載者:User

複製代碼 代碼如下:function fors(){
obj_a = obj_b;
obj_b.attr = obj_a;
}

複製代碼 代碼如下:function fors(){
obj_b = {};
obj_b.attr = obj_b;
}

上面是兩個個很顯示的循環參考,IE中產生了記憶體泄露,由於IE的記憶體回收機制,導至會長期佔用記憶體而不能釋放。

但閉包的記憶體泄露,有些隱蔽。因為閉包的循環參考,是間接的。 複製代碼 代碼如下:function iememery(){
var js_obj = document.createElement("div");
js_obj.oncontextmenu = function(){ return false;}
}
<body onload="iememery()">

從表面上看,沒有任何循環參考。但上面是一個閉包,根據閉包的特性,內建函式有權訪問外部函數的變數對象。所以當iememery()執行之後:
js_obj是一個DOM元素的引用,DOM元素它長期在網頁當中,不會消失,而這個DOM元素的一屬性oncontextmenu,又是內部的函數引用(閉包),而這個匿名函數又和js_obj之間有隱藏的關聯(範圍鏈)
所以形成了一個,循環參考.即:
js_obj.oncontextmenu 間接引用到 js_obj 也就是說,這個對象的一個屬性,又間接的引用了自己。
只要有循環參考,就會在IE下產生記憶體泄露。開啟你的windows工作管理員,在IE中不停重新整理含有這個代碼的html頁面,看看Iexploer進程的記憶體佔用情況,一直上升,且不會自動回收(降低);
解決辦法: 複製代碼 代碼如下:function iememery(){

var js_obj = document.createElement("div");
js_obj.oncontextmenu = function(){ return false;};      js_obj.oncontextmenu = null;//加上這句,斷開引用 }

當IE中發生js對象與dom對象直接的循環參考,並且之後沒有引用指向他們,
如果是IE 6, 記憶體流失,直到關閉IE進程為止
如果是IE 7,記憶體流失, 直到離開當前頁面為止
如果是IE 8, GC回收器回收他們的記憶體,無論當前是不是compatibility模式。
之前的IE js引擎裡的GC回收器只能處理js對象,不能處理DOM對象。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.