gpt4 book ai didi

javascript - javascript垃圾收集器不收集setTimeout()?

转载 作者:行者123 更新时间:2023-12-03 09:45:54 26 4
gpt4 key购买 nike

我有一个功能:

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);
}
}

至于页面刷新后仍然保持较高的内存使用率,我无法解释,但这可能与浏览器为似乎正在使用大量内存的选项卡留出更多内存有关。我不知道,只是一个猜测。

关于javascript - javascript垃圾收集器不收集setTimeout()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41270208/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com