一個JS記憶體泄露執行個體分析

來源:互聯網
上載者:User

標籤:運行   new   array   --   original   mem   另一個   long   它的   

在看JS GC 相關的文章時,好幾次看到了下面這個設計出來的例子,比較巧妙,環環相扣。 
var theThing = null;var replaceThing = function () {    var originalThing = theThing;    var unused = function () {        if (originalThing)            console.log("hi");    };    theThing = {        longStr: new Array(10000).join(‘*‘),        someMethod: function () {            console.log(1111);        }    };}; setInterval(replaceThing, 1000);

 

由於 V8 GC 的關鍵是 root 級對象,因此記憶體泄露基本上都是由於 root 級引用沒有被釋放導致的。 上面代碼中的 root 主要有兩個,一個是 theThing,另一個是 replaceThing 運行時的調用棧。這裡的記憶體泄露主要是 theThing。 總體來說是因為,root 級對象 theThing 持有了 replaceThing1 內部對象的引用,並且在下一次把引用轉交給了 replaceThing2,然後持有了 replaceThing2 的內部引用。詳細一點:theThing 持有了 longStr 和 someMethod 的引用,由於 someMethod 這個閉包會保留它的 context,因此 replaceThing 整體被保留了,於是 unused 被保留;而 unused 又持有了 originalThing 的引用,因此 originalThing 持有了 由 theThing 轉交過來的前一個 setInterval 時的 someMethod 和 longStr。 一次又一次 setInterval 下去,longStr 和 someMethod 就被串了起來。 圖解: setInterval1:   originalThing           theThing           |                           |         null             someMethod1  setInterval2:   originalThing           theThing          |                            |someMethod1    someMethod2   --unused--> replaceThing1 --> someMethod1            

一個JS記憶體泄露執行個體分析

聯繫我們

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