2011-03-11 63 views
3

我已經使用jQuery了幾個月,並閱讀了幾天的JavaScript內存泄漏。 我有一個關於內存泄漏和jQuery兩個問題:使用jQuery和內存泄漏

  1. 當我綁定(使用.bind(...))我一定要拆散他們(.unbind()),如果我離開這個頁面/刷新避免內存泄漏或jQuery爲我刪除它們?

  2. 關於關閉,我讀了他們可能導致內存泄漏,如果使用不正確。如果我做了如下操作:

    函數doStuff(objects){//對象是一個容納DOM對象數組的jQuery對象 var textColor =「red」; (function)(){ $(this).css(「color」,textColor); }); }

    doStuff($(「*」));

我知道,上面的代碼是愚蠢的(更好/更簡單[R這樣做的方法),但我想知道這是否會導致。每次循環引用/關閉的問題,它是否會導致內存泄漏。如果它確實導致內存泄漏,我將如何重寫它(通常類似的方法)以避免內存泄漏?

在此先感謝。

編輯:我有另一個類似問題2的情況下(我想這部分3)。

  1. 如果有這樣的事情:

    函數doStuff(對象){// IFRAME對象 VAR文字顏色= 「紅色」;

    function innerFunction() 
    {   
        $(this).contents().find('a').css("color", textColor); 
    } 
    
    objects.each(function(){ 
        //I can tell if all 3 are running then we 
        //have 3 of the same events on each object, 
        //this is just so see which method works/preferred 
    
        //Case 1 
        $(this).load(innerFunction); 
    
        //Case 2 
        $(this).load(function(){ 
         $(this).contents().find('a').css("color", textColor); 
        }); 
    
        //Case 3 
        $(this).load(function(){ 
         innerFunction(); 
        }); 
    }); 
    

    }
    doStuff($( 「IFRAME」));

有3種情況,我想知道哪種方法(或全部)會產生內存泄漏。此外,我想知道哪個是首選方法(通常我使用案例2)或更好的實踐(或者如果這些不好,會更好?)。

再次感謝!

回答

0

關於1.,否,當離開頁面時,您絕對不需要.unbind()。我不完全確定兩個。

1

1)否。瀏覽器清除頁面加載之間的所有內容。

2)在目前的形式中,不會有內存泄漏,因爲jquery的.each()函數沒有綁定任何東西,所以一旦它的執行完成,它傳遞的匿名函數就不再可用了,因此它的環境關閉(即關閉作爲一個整體)也無法到達。所以垃圾收集引擎可以清理所有東西 - 包括對objects的引用。

然而,如果代替.each()你有一些東西是無害的,就像$('div:eq(0)').bind()(我想強調的是,它不需要到大objects變量的引用,以至於它甚至是一個單一的元素無關),然後由於發送給.bind()的匿名函數關閉了objects變量,因此它將保持可訪問狀態,因此不會收集垃圾,從而導致內存泄漏。

避免此問題的一個簡單方法是在執行函數結束時執行objects = null;

我應該注意到我並不熟悉JS垃圾收集引擎,所以有可能有合理的智能優化。例如,可以檢查匿名函數是否嘗試訪問任何關閉的變量,如果不是,它可能會將它們傳遞給垃圾回收器,這可以解決問題。

要進一步閱讀,請查找對javascript的內存模型的引用,特別是環境模型和靜態綁定。

0

關於1,有時你必須釋放你的資源,特別是當你有循環引用和使用Internet Explorer時(因爲有一些錯誤,因爲理論上你不應該這麼做);)谷歌地圖有一個函數他們的v2,以防止我們不得不呼籲document.onunload(GUnload)。

關於2,您沒有循環引用。它消耗大量的內存,因爲this必須有自己的執行上下文以訪問textColor等等。

循環引用是在對象引用自身或閉包自行調用時實現的。也許還有其他情況..

希望這有助於

+0

如果沒有必要的循環引用,可能會導致封閉泄漏 – davin 2011-03-11 03:00:02

1

有一些細微的泄漏模式,你甚至可能不會承認。看看我前一段時間提到的有關類似問題的一個問題 jQuery 1.5 Memory leak in IE8

如果在引用dom節點的對象周圍創建一個閉包,會產生一個泄漏的引用循環,不幸的是,它不能被簡單地糾正解除綁定。您將不得不將對象中的DOM節點的引用設置爲null。

+0

我不同意,只是因爲有一個對象引用了一些DOM節點,並不意味着有泄漏。在這種特殊情況下,在函數執行結束時不再可以訪問對象,因此有資格進行垃圾回收==>沒有內存泄漏。 – davin 2011-03-11 03:06:52

+0

理論上,情況就是這樣。但是,在某些情況下,一旦在IE(object-> node-> eventHandler-> object)中創建了一個引用循環,它就永遠不會被釋放,即使您將eventHandler(object-> node X eventHandler-> object )。請在我提供的鏈接中嘗試jsFiddle並觀看taskManager – jordancpaul 2011-03-11 03:11:09

+0

在這裏的代碼中沒有循環引用,所以雖然在這種情況下您可能是正確的,但在此處不適用。 – davin 2011-03-11 03:14:19