JavaScript記憶體流失

來源:互聯網
上載者:User

1、什麼是閉包、以及閉包所涉及的範圍鏈這裡就不說了。

2、JavaScript記憶體回收機制 

     JavaScript不需要手動地釋放記憶體,它使用一種自動記憶體回收機制(garbage collection)。當一個對象無用的時候,即程式中無變數引用這個對象時,就會從記憶體中釋放掉這個變數。

 

var s = [ 1, 2 ,3];    var s = null;    //這樣原始的數組[1 ,2 ,3]就會被釋放掉了。

 

3、循環參考

     三個對象 A 、B 、C

     AàBàC :A的某一屬性引用著B,同樣C也被B的屬性引用著。如果將A清除,那麼B、C也被釋放。

     AàBàCàB :這裡增加了C的某一屬性引用B對象,如果這是清除A,那麼B、C不會被釋放,因為B和C之間產生了循環參考。

 var a = {};    a.pro = { a:100 };    a.pro.pro = { b:100 };    a = null ;     //這種情況下,{a:100}和{b:100}就同時也被釋放了。                var obj = {};    obj.pro = { a : 100 };    obj.pro.pro = { b : 200 };    var two = obj.pro.pro;    obj = null;        //這種情況下 {b:200}不會被釋放掉,而{a:100}被釋放了。

4、循環參考和閉包

function outer(){        var obj = {};        function inner(){             //這裡引用了obj對象        }        obj.inner = inner;    }

這是一種及其隱形循環參考,。當調用一次outer時,就會在其內部建立obj和inner兩個對象,obj的inner屬性引用了inner;同樣inner也引用了obj,這是因為obj仍然在innerFun的封閉環境中,準確的講這是由於JavaScript特有的“範圍鏈”。
因此,閉包非常容易建立循環參考,幸運的是JavaScript能夠很好的處理這種循環參考。

5、IE中的記憶體流失

    IE中的記憶體流失有好幾種,這裡有詳細的解釋(http://msdn.microsoft.com/en-us/library/bb250448.aspx),園子裡也有翻譯了(http://www.cnblogs.com/birdshome/archive/2006/05/28/ie_memoryleak.html)。

    這裡只討論其中一種,即循環參考所造成的記憶體流失,因為,這是一種最普遍的情況。

    當在DOM元素或一個ActiveX對象與普通JavaScript對象之間存在循環參考時,IE在釋放這類變數時存在特殊的困難,最好手動切斷循環參考,這個bug在IE 7中已經被修複了(http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html)。

   “IE 6 suffered from memory leaks when a circular reference between several objects, among which at least one DOM node, was created. This problem has been solved in IE 7. ”

    如果上面的例子(第4點)中obj引用的不是一個JavaScript Function對象(inner),而是一個ActiveX對象或Dom元素,這樣在IE中所形成的循環參考無法得到釋放。

 

function init(){        var elem = document.getElementByid( 'id' );        elem.onclick = function(){            alert('rain-man');            //這裡引用了elem元素        };    }

Elem引用了它的click事件的監聽函數,同樣該函數通過其範圍鏈也引用回了elem元素。這樣在IE中即使離開當前頁面也不會釋放這些循環參考。

6、解決方案

   基本的方法就是手動清除這種循環參考,下面一個十分簡單的例子,實際應用時可以自己構建一個addEvent()函數,並且在window的unload事件上對所有事件綁定進行清除。

function outer(){        var one = document.getElementById( 'one' );        one.onclick = function(){};    }    window.onunload = function(){        var one = document.getElementById( 'one' );        one.onclick = null;    };

其它方法(by:Douglas Crockford)

/** * 遍曆某一元素節點及其所有後代元素 * * @param Elem node  所要清除的元素節點 * @param function func  進行處理的函數 *  */function walkTheDOM(node, func) {    func(node);     node = node.firstChild;     while (node) {         walkTheDOM(node, func);         node = node.nextSibling;     } } /** * 清除dom節點的所有引用,防止記憶體泄露 * * @param Elem node  所要清除的元素節點 *  */function purgeEventHandlers(node) {    walkTheDOM(node, function (e) {        for (var n in e) {                        if (typeof e[n] ===                     'function') {                e[n] = null;            }        }    });

 

 

相關文章

聯繫我們

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