閉包造成的內存泄露如何解決


什么是閉包?
閉包就是一個函數,能夠訪問其他函數內部變量的函數

閉包示例代碼

function outer() {
     var  a = '變量1'
     var  inner = function () {
            console.info(a)
     }
     return inner    // inner 就是一個閉包函數,因為他能夠訪問到outer函數的作用域
}
var  inner = outer()   // 獲得inner閉包函數
inner()   //"變量1"

當程序執行完var inner = outer(),其實outer的執行環境並沒有被銷毀,因為他里面的變量a仍然被被inner的函數作用域鏈所引用,當程序執行完inner(), 這時候,inner和outer的執行環境才會被銷毀調;《JavaScript高級編程》書中建議:由於閉包會攜帶包含它的函數的作用域,因此會比其他函數占用更多內容,過度使用閉包,會導致內存占用過多。

  • 基本類型變量(Number 、Boolean、Undefined、String、Null)的值一般都是存在棧內存中,
  • 引用類型變量(Array、Object、Function)的值存儲在堆內存中,棧內存存儲對應空間地址

閉包的作用
1.訪問其他函數內部變量
2.保護變量不被內存回收機制回收
3.避免全局變量被污染 方便調用上下文的局部變量 加強封裝性

閉包的缺點
閉包長期占用內存,內存消耗很大,可能導致內存泄露

如何避免閉包引起的內存泄漏
1,在退出函數之前,將不使用的局部變量全部刪除。可以使變量賦值為null;(示例如下)

 這段代碼會導致內存泄露
    window.onload = function(){
        var el = document.getElementById("id");
        el.onclick = function(){
            alert(el.id);
        }
    }
    解決方法為
    window.onload = function(){
        var el = document.getElementById("id");
        var id = el.id;                                      //解除循環引用
        el.onclick = function(){
            alert(id); 
        }
        el = null;                                          // 將閉包引用的外部函數中活動對象清除
    }

2,避免變量的循環賦值和引用。 (示例如上)

循環引用引起的內存泄漏,是因為IE 的bug,循環引用無法自動判斷,所以通過拷貝值,把內外引用脫鈎,這樣就可回收。IE9及其以后已修復。(感謝 貓SirSir 的講解!)

3,利用Jquery釋放自身指定的所有事件處理程序。
由於jQuery考慮到了內存泄漏的潛在危害,所以*它會手動釋放自己指定的所有事件處理程序 *。只要堅持使用jQuery的事件綁定方法,就可以一定程度上避免這種特定的常見原因導致的內存泄漏。

這段代碼會導致內存泄露
$(document).ready(function() {
    var button = document.getElementById('button-1');
    button.onclick = function() {
         console.log('hello');
         return false;
    };
});
當指定單擊事件處理程序時,就創建了一個在其封閉的環境中包含button變量的閉包。
而且,現在的button也包含一個指向閉包(onclick屬性自身)的引用。
這樣,就導致了在IE中即使離開當前頁面也不會釋放這個循環。 用jQuery化解引用循環 $(document).ready(
function() { var $button = $('#button-1'); $button.click(function(event) { event.preventDefault(); console.log('hello'); }); });

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM