Javascript的記憶體流失分析

來源:互聯網
上載者:User

標籤:move   前端開發   情況下   利用   span   tle   bag   default   jquery   

     作為程式員(更高大尚的稱謂:研軟體研發)的我們,無論是用Javascript,還是.net, java語言,肯定都遇到過記憶體流失的問題。只不過他們都有GC機制來協助程式員完成記憶體回收的事情,如果你是C++開發人員(你懂的)。。。。。,如果你是前端開發人員,肯定在使用Javascript(你或者會說,Js是世界上最棒的語言),但我這裡也得告訴你,Js的記憶體流失會來得更為突然,或者讓你都無法察覺。本文就帶大家領略一下Js的風騷:

一、模組化引起的記憶體流失

代碼如下:

// module date.jslet date = null;export default {    init () {        date = new Date();    }}// main.jsimport date from ‘date.js‘;date.init();

      上述是我們在現代前端工程方案中常見的代碼格式,寫一個模組,然後匯出這一個模組。這裡你應該知道date.js中的date是靜態(也就是你在N處匯入date.js這個模組),但他們的date這個變數是共用的,一處改變,其他地方也對應發生變化。

 

二、假OOP範式引起的記憶體流失

在這裡我為什麼叫他假OOP呢,原因是這代碼是想實現OOP範式卻讓自己掉到坑裡去了,先上代碼:

var fun = function(arg){    this.sarg = arg;     var self = this;    return function(){        console.log(self.sarg);    }}var fn = new fun(‘data arg‘);fn();

首先,定義fun這個函數變數,然後返回一個function(這可以說就是典型的閉包)。閉包函數內引用外面的this對象(var self = this)。

然後,通過new的方式調用fun,傳回值用fn接受,這裡誰都知道返回的是一個函數,所以可以括弧運算子進行執行。

2.1 利用chrome的memory面板進行分析

      定位到memory面板,然後重新整理頁面,再單擊中所示的 ‘collect garbage‘表徵圖(也就是像資源回收筒的表徵圖),強制進行一次gc的回收,這樣可以確保我們分析的對象就是可以存在記憶體流失的對象(至少他們是gc不可回收的對象)。

此圖是上述程式碼片段在chrome瀏覽器中執行完成後,不能被gc回收的記憶體變數。 2.2 我認為的原因

先貼出發生記憶體流失的代碼

var fun = function(arg){    this.sarg = arg; //記憶體流失    var self = this;//記憶體流失    return function(){        console.log(self.sarg);//記憶體流失    }}var fn = new fun(‘data arg‘); //記憶體流失fn();

我認為的原因有以下幾點:

1. 使用new運算子,他會建立一個對象,然後執行建構函式,並將建構函式對應的prototype(也就是原型)複製到新的對象上。

2. 上述new出來的新對象,在執行建構函式時,其this就指向了這個new出來的新對象

3. 然後上述代碼在建構函式中又返回了一個函數,且函數中引用了new出來的新對象,返回函數賦值給了fn變數

4. 最的執行fn變數,正確輸出我們想要的內容,這樣程式就跑了(可以,我們new出來的新對象,沒有人管也了,所以他就泄漏了)。2.3 總結:

     因為正常情況下,我們對一個function進行new操作的時候,在建構函式內是不會進行返回的,其實這個時候new操作預設給你返回的就是建構函式中的this對象。上述代碼不建議出現在項目代碼中,這是典型的錯誤寫法,並樣本只是為了示範泄漏。

  三、DOM事件引起的記憶體流失

如果你是Jquery的忠粉,這部分可能對你有協助,先上代碼:

//html:<input type="file" id="file" /><button type="button" onclick="remove()" >but</button>//js:var file = document.getElementById("file");file.addEventListener(‘change‘,function(event){    console.log(event.target.value);});function remove(){    file.remove();}

首先我們在html中寫兩個標籤,一個是file、一個是button;然後在js中對file標籤綁定了change事件,然後對button綁定一個remove方法,用於移除file標籤。

3.1 記憶體流失分析

在我們執行了remove方法後,然後收集記憶體分析:

     我們還按照樣本二相同的操作,開啟memory面板,然後執行一次GC回收後收集記憶體資料,然後查看Detached Dom tree(這就表示與DOM樹失去聯絡的對象),然後我們把滑鼠移動到native上,就會顯示記憶體流失的代碼位置。

Jquery忠粉們可以注意了,無論你是用的bind還是on進行事件的綁定,如果你在移除這些DOM元素前,沒有進行相應的unbind或是off操作,那麼恭喜你,記憶體一定泄漏了。

Javascript的記憶體流失分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.