垃圾回收機制html
JavaScript不須要手動地釋放內存,它使用一種自動垃圾回收機制(garbage collection)。當一個對象無用的時候,即程序中無變量引用這個對象時,就會從內存中釋放掉這個變量編程
循環引用瀏覽器
三個對象 A 、B 、C閉包
A->B->C :A的某一屬性引用着B,一樣C也被B的屬性引用着。若是將A清除,那麼B、C也被釋放。app
A->B->C->B :這裏增長了C的某一屬性引用B對象,若是這是清除A,那麼B、C不會被釋放,由於B和C之間產生了循環引用。函數
1 var a = {}; 2 a.pro = { a:100 }; 3 a.pro.pro = { b:100 }; 4 a = null ; 5 //這種狀況下,{a:100}和{b:100}就同時也被釋放了。 6 7 var obj = {}; 8 obj.pro = { a : 100 }; 9 obj.pro.pro = { b : 200 }; 10 var two = obj.pro.pro; 11 obj = null; 12 //這種狀況下 {b:200}不會被釋放掉,而{a:100}被釋放了。
循環引用和閉包this
1 function outer(){ 2 var obj = {}; 3 function inner(){ 4 //這裏引用了obj對象 5 } 6 obj.inner = inner; 7 }
DOM循環引用spa
function SetupLeak() { myGlobalObject = document.getElementById("LeakedDiv"); document.getElementById("LeakedDiv").expandoProperty = myGlobalObject; }
IE下的內存泄露code
在IE下的JS編程中,如下的編程方式都會形成即便關閉IE也沒法釋放內存的問題,下面分類給出:
一、給DOM對象添加的屬性是一個對象的引用。範例:
var MyObject = {};
document.getElementById('myDiv').myProp = MyObject;
解決方法:
在window.onunload事件中寫上: document.getElementById('myDiv').myProp = null;
二、DOM對象與JS對象相互引用。範例:
function Encapsulator(element) {
this.elementReference = element;
element.myProp = this;
}
new Encapsulator(document.getElementById('myDiv'));
解決方法:
在onunload事件中寫上: document.getElementById('myDiv').myProp = null;
三、給DOM對象用attachEvent綁定事件。範例:
function doClick() {}
element.attachEvent("onclick", doClick);
解決方法:
在onunload事件中寫上: element.detachEvent('onclick', doClick);
四、從外到內執行appendChild。這時即便調用removeChild也沒法釋放。範例:
var parentDiv = document.createElement("div");
var childDiv = document.createElement("div");
document.body.appendChild(parentDiv);
parentDiv.appendChild(childDiv);
解決方法:
從內到外執行appendChild:
var parentDiv = document.createElement("div");
var childDiv = document.createElement("div");
parentDiv.appendChild(childDiv);
document.body.appendChild(parentDiv);
五、反覆重寫同一個屬性會形成內存大量佔用(但關閉IE後內存會被釋放)。範例:
for(i = 0; i < 5000; i++) {
hostElement.text = "asdfasdfasdf";
}
這種方式至關於定義了5000個屬性! htm
總結一下,內存泄露分爲四類:
一、循環引用(Circular References) — IE瀏覽器的COM組件產生的對象實例和網頁腳本引擎產生的對象實例相互引用,就會形成內存泄漏。
這也是Web頁面中咱們遇到的最多見和主要的泄漏方式;
二、內部函數引用(Closures) — Closures能夠當作是目前引發大量問題的循環應用的一種特殊形式。因爲依賴指定的關鍵字和語法結構,
Closures調用是比較容易被咱們發現的;
三、頁面交叉泄漏(Cross-Page Leaks) — 頁面交叉泄漏實際上是一種較小的泄漏,它一般在你瀏覽過程當中,因爲內部對象薄計引發。下面咱們
會討論DOM插入順序的問題,在那個示例中你會發現只須要改動少許的代碼,咱們就能夠避免對象薄計對對象構建帶來的影響;
四、貌似泄漏(Pseudo-Leaks) — 這個不是真正的意義上的泄漏,不過若是你不瞭解它,你可能會在你的可用內存資源變得愈來愈少的時候極
度鬱悶。爲了演示這個問題,咱們將經過重寫Script元素中的內容來引起大量內存的"泄漏"。
詳細能夠參照:http://www.cnblogs.com/carekee/articles/1733847.html