js的內存泄露

轉:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScriptjavascript

使用閉包的一個壞處是,在 IE 瀏覽器中它會很容易致使內存泄露。JavaScript 是一種具備垃圾回收機制的語言——對象在被建立的時候分配內存,而後當指向這個對象的引用計數爲零時,瀏覽器會回收內存。宿主環境提供的對象都是按照這種方法被處理的。java

瀏覽器主機須要處理大量的對象來描繪一個正在被展示的 HTML 頁面——DOM 對象。瀏覽器負責管理它們的內存分配和回收。瀏覽器

IE 瀏覽器有本身的一套垃圾回收機制,這套機制與 JavaScript 提供的垃圾回收機制進行交互時,可能會發生內存泄露。數據結構

在 IE 中,每當在一個 JavaScript 對象和一個本地對象之間造成循環引用時,就會發生內存泄露。以下所示:閉包

function leakMemory() {
    var el = document.getElementById('el');
    var o = { 'el': el };
    el.o = o;
}

這段代碼的循環引用會致使內存泄露:IE 不會釋放被 el 和 o 使用的內存,直到瀏覽器被完全關閉並重啓後。函數

這個例子每每沒法引發人們的重視:通常只會在長時間運行的應用程序中,或者由於巨大的數據量和循環中致使內存泄露發生時,內存泄露才會引發注意。this

不過通常也不多發生如此明顯的內存泄露現象——一般泄露的數據結構有多層的引用(references),每每掩蓋了循環引用的狀況。code

閉包很容易發生無心識的內存泄露。以下所示:對象

function addHandler() {
    var el = document.getElementById('el');
    el.onclick = function() {
        el.style.backgroundColor = 'red';
    }
}

這段代碼建立了一個元素,當它被點擊的時候變紅,但同時它也會發生內存泄露。爲何?由於對 el 的引用不當心被放在一個匿名內部函數中。這就在 JavaScript 對象(這個內部函數)和本地對象之間(el)建立了一個循環引用。blog

這個問題有不少種解決方法,最簡單的一種是不要使用 el 變量:

function addHandler(){
    document.getElementById('el').onclick = function(){
        this.style.backgroundColor = 'red';
    };
}

 另一種避免閉包的好方法是在 window.onunload 事件發生期間破壞循環引用。不少事件庫都能完成這項工做。注意這樣作將使 Firefox 中的 bfcache 沒法工做。因此除非有其餘必要的緣由,最好不要在 Firefox 中註冊一個onunload 的監聽器。

相關文章
相關標籤/搜索