js記憶體洩露

weixin_34007886發表於2017-03-24

js記憶體洩露

js記憶體的機制

  1. js的基本變數 boolean string number null undefined symbol 是分配在棧上的
  2. js的引用型別是分配在堆上面的
  3. 記憶體洩露只會發生在對堆區

js記憶體回收機制

js是用標記清楚法,部分Ie低版本使用引用計數法進行垃圾回收

上面叫記憶體洩露呢?

記憶體洩露就是 記憶體洩漏是指我們已經無法再通過js程式碼來引用到某個物件,但垃圾回收器卻認為這個物件還在被引用,因此在回收的時候不會釋放它 上面這句話就說成了記憶體洩露的根本

下面分析一段記憶體洩露的程式碼

      var demo = document.getElementById('demo');;
      var username = {name: 'username'}; //在堆上面生成一個物件
      demo.onclick = function() {
        this.innerHTML = username.name; //這裡面對username進行引用
      }
      username = null; //username 置為空      var demo =    document.getElementById('demo');;
      var username = {name: 'username'}; //在堆上面生成一個物件
      demo.onclick = function() {
        this.innerHTML = username.name; //這裡面對username進行引用
      }
      username = null; //username 置為空

上面的程式碼傳送記憶體洩露了麼?
確實是發生了, onclick函式裡面引用username, js解析器會標記這個堆地址在onclick裡面會有引用, 雖然最後我們設定username = null, onclick裡面的標記並沒有清楚,即我們無法通過程式碼進行引用到之前建立的username對應的堆的這個地址,也無法清楚js解析器標記的,onclick裡面對這個堆地址的引用。所以發生記憶體洩露

那如何才能避免發生這樣情況呢? 有兩種,一種是保證 這個堆地址能被我們js程式碼控制,另外一個的話,由於是onclick發生洩露,所以我們可以 設定 onclick = null

再來看另外一個情況

function bindEvent() 
{ 
    var obj = document.createElement("XXX"); 
    obj.onclick = function(){ 
        // ... 
    } 
}

bindEvent();

上面的傳送洩露了麼? 發生了,注意是這個dom上面的onclick函式比較特殊,它會把
onclick函式註冊到外面去,相當於閉包暴露在外面了,所以bindEvent會建立一個閉包,而且對於裡面生成的的obj,我們是無法引用的到的,所以發生了記憶體洩露

參考: js的閉包和回撥到底怎麼才會造成真的記憶體洩漏呢?

相關文章