簡體   English   中英

JavaScript垃圾收集這個嗎?

[英]Does JavaScript garbage collect this?

每隔一段時間我就會發現自己在做下面的事情

var img = new Image();
img.src = 'php/getpic.php?z=' + imid + '&th=0';
img.onload = function(){drawImages(img,contexts,sizes)};

說明

  1. 創建HTML圖像元素。
  2. 分配其src屬性
  3. 分配其onload事件
  4. 將一個或多個Canvas上下文傳遞給事件處理程序
  5. 將加載的圖像繪制到畫布上

我不清楚的是這個問題 - JavaScript垃圾收集器是否會處理丟棄img元素的任務,或者我是否需要自己執行此操作,否則將面臨一個低內存泄漏?

它將在IE 6和7 (以及非常舊版本的FF)中泄漏 ,因為它在JavaScript和DOM之間創建了循環引用。 IE 6和7不能垃圾收集在兩個世界之間具有循環引用的任何對象,因為它們使用單​​獨的垃圾收集器。

現代瀏覽器可以處理這個而不會泄漏。

為防止它在IE 6和7中泄漏,請在完成img執行此操作:

img.onload = null;

如果您只關心現代瀏覽器,則不必擔心它。 (我很高興IE 6和7的市場份額最終足夠低,以表明這一點!)


更新

您為onload分配的函數會創建一個閉包。 該閉包包含對img的引用。 只要該閉包存在於JScript的內存中(JScript是JavaScript的IE實現的名稱), img就不能從DOM的內存中進行垃圾收集。 同樣,只要img存在於DOM的內存中,閉包就不能從JScript的內存中進行垃圾收集,因為img.onload具有對你的函數的引用。 這是一個循環參考。 換句話說,僅僅因為drawImages執行一次並不意味着它不會再次執行(JScript引擎不知道onload只會觸發一次 - 這是DOM的域),所以JScript必須保持閉包活着。

您顯示的模式是已知在IE 6和7中創建內存泄漏的經典模式。它包括(1)DOM節點,(2)該DOM節點上創建閉包的事件處理程序,(3) )返回閉包內DOM節點的引用。

如果您擔心內存泄漏,我建議您使用Google Chrome堆調試器 在您的情況下,我做了一個簡單的測試,可以驗證您的特定模式是否會產生內存泄漏。

<html>
    <head>
        <script>
            function test() {
                var img = new Image();
                img.src = 'php/getpic.php?z=1&th=0';
                img.onload = function(){ drawImages(img,contexts,sizes); };
            }
        </script>
    </head>
    <body>
        <input type="button" onclick="test()" value="test" />
    </body>
</html>

我建議你在測試之前按“test”一次,以避免結果中出現不必要的噪音(在第一次代碼運行時,內存中會添加一些東西,這並不意味着內存泄漏)。

獲取堆快照,按測試並獲取堆快照。 如果您想要實際結果,則必須將視圖從“摘要”切換為“比較” 如果視圖為空(在我測試的情況下),則表示在該步驟期間未添加任何內容,這意味着它沒有內存泄漏。 在另一種情況下,它將顯示快照之間添加或刪除的內容。

注意:此方法無法幫助您解決具有自身問題的舊瀏覽器的內存泄漏問題,但這是在大多數現代瀏覽器中找到會導致內存泄漏的問題的一個很好的步驟。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM