3

有沒有人知道爲什麼內存消耗在這裏保持不變?Javascript內存泄漏setTimeout問題

var count = 0; 
$(init); 

function init(){ 
    var node = document.querySelector('.logs'); 

    function check(){ 
     var uArr = new Uint16Array(100); 
     log(node, uArr.length); 
     setTimeout(check,100); 
    } 
    setTimeout(check,100); 
}  


function log(node, text){ 
    if(count % 30 == 0){ 
     node.innerHTML = ''; 
    } 
    var child = document.createElement('div'); 
    child.innerText = 'count ' + (count++) + " arr len " + text; 
    node.appendChild(child); 
} 

http://jsfiddle.net/V99Eb/11/

之所以應該線性增加內存分配是:「檢查」方法調用它本身的定義裏面,所以關閉變量將提供給內部檢查方法執行,然後再爲測試功能創建一個執行上下文等等。另外,在每個執行過程中,我們創建一個Uint16Array的內存塊,我相信這個內存塊是分配在堆中的,並且不應該因爲它可以從閉包中獲得而被取消分配。

內存簡介: enter image description here

綜觀內存時間表,它似乎並沒有增加內存分配隨着時間增加而增加。這是預期的行爲?

+0

爲什麼你的標題聲稱內存泄漏問題,實際上你證明沒有內存泄漏? –

+1

'uArr'只是一個局部變量,它的生存期只是'check()'的當前執行。只要一次調用'check()'完成,該調用的局部變量就有資格收集垃圾,因爲不再有任何代碼可以到達它們。唯一在閉包中無限存活的變量是'node'。 – jfriend00

回答

3

uArr只是一個局部變量,在check()退出後被分配,使用和垃圾回收。 check()內沒有關閉。 setTimeout()被調用(但未定義)check()

This page on Closures可能有幫助。

雖然這是真的,如果有N個來電check(),就已經生成的N封(以及對node N份),setTimeout()將發佈其參考check()它調用後。因此,那裏也沒有泄漏。

+0

你的第一句話並不完全正確。如果您將一個匿名完成回調函數的異步函數調用爲一個執行N次迭代的for循環的參數,那麼您將得到N個單獨的閉包。佈局確定會有閉包,但是由於執行的路徑,N閉包自己被創建爲執行的代碼。 – jfriend00

+0

@ jfriend00你是對的。謝謝!我修改了我的答案。 – cybersam