[英]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.