簡體   English   中英

javascript垃圾收集器沒有收集setTimeout()s?

[英]javascript garbage collector not collecting setTimeout()s?

我有一個功能:

function test()
{
            for( var i = 0; i < 1000000; i++ )
            {
                setTimeout( function()
                {
                    //
                }, 10000 );
            }
}

在chrome上運行它,它可以將內存使用量從大約50MB推進到600MB,我猜這是可以的; 但是在執行了超時之后,垃圾收集器似乎並沒有將它們從內存中刪除,它只是保持在600MB直到我刷新,即使這樣,它在頁面刷新后會留下150MB的某種“足跡”。

任何想法如何告訴垃圾收集器在執行后擺脫它們?

你是正確的,似乎有永遠不會清理的內存。 我對這個問題的最好猜測是在這樣的 for循環中創建一個函數會創建一個必須有權訪問 i的新范圍。 因此,這些功能永遠不會被清理。 我想錯了 - 功能一定要清理干凈。 在我的瀏覽器中進行測試使內存超過900MB。

重要的是要注意做你正在做的事情沒有任何好處,它最多可歸類為“糟糕的代碼”。 您應該創建一個函數並重用它:

// reusing a function fixes the problem
function test () {
    var fn = function () {};
    for (var i = 0; i < 1000000; i++) {
        setTimeout(fn, 1000);
    }
}

我的觀察結果是,內存使用量回升超過900MB,然后在幾分鍾內逐漸回落至接近正常狀態。

如果您需要訪問函數內部的變量i ,我不願意說您的代碼不會給您這樣做。 你只會看到i (1000000)最后一個值 如果您想在函數中使用i ,可以使用工廠函數。 在我的測試中,內存最終得到了清理:

// using a factory fixes the problem and give you access to 'i'
function test () {
    function factory (n) {
        return function () {
            /* This will get called later. 'n' will represent
               the value of 'i' at the time this function was created */
        }
    }
    for (var i = 0; i < 1000000; i++) {
        setTimeout(factory(i), 1000);
    }
};

不幸的是,如果你使用bind ,內存問題仍然存在:

// Memory problem still exists with .bind
function test () {
    var fn = function (n) { };
    for (var i = 0; i < 1000000; i++) {
        setTimeout(fn.bind(null, i), 1000);
    }
}

至於頁面刷新后內存使用量仍然很高,這個我無法解釋,但它可能與瀏覽器設置為顯示使用大量內存的選項卡留出更多內存。 我不知道,只是一個猜測。

暫無
暫無

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

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