【问题标题】:Trying to Understand Javascript Closures + Memory Leaks试图理解 Javascript 闭包 + 内存泄漏
【发布时间】:2012-04-20 23:16:36
【问题描述】:

我已经阅读了很多关于 Javascript 中的闭包的文章。我来自更传统的(C、C++ 等)背景并了解调用堆栈等,但我在 Javascript 中的内存使用方面遇到了麻烦。这是我设置的(简化的)测试用例:

function updateLater(){
    console.log('timer update');

    var params = new Object();
    for(var y=0; y<1000000; y++){
        params[y] = {'test':y};
    }
}

或者,我也尝试过使用闭包:

function updateLaterClosure(){

return (function(){

    console.log('timer update');
    var params = new Object()
    for(var y=0; y<1000000; y++)
    {
        params[y] = {'test':y};
    }
});
}

然后,我设置了运行函数的时间间隔...

setInterval(updateLater, 5000); // or var c = updateLaterClosure(); setInterval(c,5000);

计时器第一次运行时,内存使用量从 50MB 跃升至 75MB(根据 Chrome 的任务管理器)。第二次超过 100MB。偶尔它会回落一点,但绝不会低于 75MB。

请自行查看:https://local.phazm.com:4435/Streamified/extension/branches/lib/test.html

显然,params 没有被完全垃圾收集,因为第一次计时器调用的内存没有被释放......然而,它也没有在每次调用时增加 25MB 的内存,所以它不像垃圾收集永远不会发生……似乎总是保留一个“参数”实例。我已经尝试过设置子闭包和其他东西......没有骰子。

不过,最令人不安的是内存使用量呈上升趋势。它现在可能“只是”75MB,但让它运行足够长的时间(一夜之间),它会达到 500MB。

想法?

谢谢!

【问题讨论】:

  • 请记住:Java != Javascript。与 Java 不同,每个浏览器可能有完全不同的垃圾收集实现。例如:javascript.crockford.com/memory/leak.html
  • re: java vs. javascript:: 当然 - 这不是我第一次参加牛仔竞技表演,但感谢您的提醒 ;) 不幸的是,我现在时间紧迫,没有时间阅读整本书只是为了找到解决这个问题的方法:(
  • 您在系统任务管理器中看到的 Chrome 内存使用情况是应用程序正在使用的总内存。其中一些内存实际上可能会保留以供将来在应用程序中使用。所以,仅仅因为你的内存上升一次并且没有下降并不意味着你有泄漏。可能是 Chrome 从系统分配的供将来使用的内存池更大。只要不重复使用,就不是泄漏。
  • @jfriend00 令人着迷——我想我希望它更像一个调试器/分析器来告诉你当前的内存分配。不幸的是,对我来说,它确实呈上升趋势(尽管呈锯齿形)。

标签: javascript performance memory-leaks


【解决方案1】:

分配 25mb 会导致 GC 发生。此 GC 清理最后一个实例,但当然不是当前实例。所以你总是有一个实例。

程序空闲时不会发生 GC。它不会在您的计时器调用之间发生,因此内存会保留。

【讨论】:

  • 好的……那么有什么方法可以触发手动垃圾回收吗?我正在构建的内容需要在计时器上分配相当大的内存块......它基本上最终(最终)爆炸页面。
  • 不在 JavaScript 中。没有浏览器支持它。其实,除了分配少,我对你没有什么建议。
  • 不幸的是,分配更少不是一种选择。在实际场景中,我正在解析来自服务器的 JSON 数据(在计时器上使用 AJAX 命令)。结果对象不小。
  • 也...这并不能解释为什么内存使用量会随着时间的推移呈上升趋势。
  • 嗯,我无法在 chrome 中复制它。一小时后我得到恒定的〜25mb。
【解决方案2】:

这甚至不是一个闭包。 A closure is when you return 来自函数的某些东西,例如数组、函数、对象或任何可以包含引用的东西,它带有该函数的所有本地成员。

你所拥有的只是一个非常长的循环正在构建一个非常大的对象的情况。也许你的记忆不会像你建造巨大的物体那样快地被回收。

【讨论】:

  • 你是对的。我最初设置了一个闭包(具有相同的效果),但为了这个问题的上下文对其进行了简化,但在编写它时并没有充分改变我的词汇以使这一点变得明显。无论如何,闭包和普通函数似乎都不起作用。
  • 您能否至少发布一个简化的闭包结构案例,以及它返回后的存储位置。
  • 我刚刚更新了页面以改用闭包:local.phazm.com:4435/Streamified/extension/branches/lib/… 只是想指出:内存使用量也随着时间的推移呈上升趋势(尽管速度很慢)。
  • 你能把代码贴出来吗?如果该链接失效,您的帖子将在未来变得毫无意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 2020-03-27
  • 2013-01-11
  • 2013-03-29
  • 2013-07-12
  • 1970-01-01
  • 2016-01-12
相关资源
最近更新 更多