在谷歌浏览器中强制进行垃圾回收

54

我们正在使用ZK开发单页Web应用程序,该应用程序与服务器不断通信并更新其屏幕的部分内容。更新频率可以高达1秒。在这些更新过程中,对大量JS对象的引用会丢失,这些对象最终必须通过垃圾收集器进行清理。

据我们所知,Chrome仅在非活动标签上运行其垃圾回收器。这对我们来说是个问题,因为应用程序的标签通常是活动状态并且几乎从不刷新,因此JS对象永远不会被收集。如果保持足够长的时间处于活动状态,标签最终会崩溃(显示Aww Snap信息)。

我们需要手动启动垃圾收集。到目前为止,我们已经尝试使用--js-flags="--expose-gc"运行Chrome并运行gc(),但它会抛出异常:

ReferenceError: gc is not defined

在 Firefox 上不会发生这种情况 - 内存使用量多少是恒定的。

强制刷新页面不是一个选项。

我们将非常感激任何建议。

编辑:我们已经尝试在 Chrome 版本 23.0.1271.97 m25.0.1364.2 dev-m 上运行 window.gc()gc()


6
据我们了解,Chrome只在非活动标签页上运行垃圾回收器。不,这是不正确的。Chrome会在感觉需要的任何时候运行GC,无论标签页是否处于活动状态。 - T.J. Crowder
5
这里提到的是 window.gc(),但据我所知,它只在 Chrome 的调试版本中有效,并不是最终解决方案。正如 Crowder 指出的那样,Chrome 会在需要时运行它,因此如果您的应用程序存在内存泄漏问题,您应该检查您的代码,尽可能明确地释放已分配的对象。 - Adriano Repetti
4
在JavaScript中,delete关键字与内存管理无关,除非你使用它来删除一个对象的唯一引用属性,那么它只会作为一个副作用而触发内存管理。 - T.J. Crowder
2
@Cerbrus: :-) 只是避免那个神话继续流传下去(哇,Brendan 应该称它为 remove 或其他什么,但嘿,他当时承受了巨大的时间压力...)。 - T.J. Crowder
1
@guilty:我不这样解读那个线程,我认为有人在说内存没有被释放得像他们想象中的那样快,还有人说他们认为他们可以引起Aw snap!,但是却没有提供任何支持数据。显然,如果您可以通过反复拖动图像来崩溃Chrome,那将不是一个WontFix的情况。 - T.J. Crowder
显示剩余3条评论
3个回答

46
您可以获取 Chrome 开发者工具的代码,修改它以便每隔一段时间调用 ProfilerAgent.collectGarbage();(这是在时间轴面板上单击“收集垃圾”按钮时调用的代码),然后使用 --debug-devtools-frontend 标志运行带有您版本的 DevTools 的 Chrome 浏览器。
然而,这种解决方案相当极端,只有在你真的很绝望的时候才尝试。在此之前,我建议对应用程序进行分析,并查看为什么 v8 决定不清除垃圾(或无法清除垃圾)。DevTools 的时间轴面板将帮助您完成此操作。首先检查该面板底部的“收集垃圾”按钮是否起作用,如果没有 - 您可能有内存泄漏(至少根据 v8 的说法)。如果是这样,请尝试使用leak-finder-for-javascript
[编辑] 我删除了关于 Chrome 扩展的信息,因为事实证明当使用 --js-flags="--expose-gc" 时,可以从网页代码中调用 gc()。至少在我的 23.0.1271.64 版本上是这样的。

5
原文:It turns out you have to close all current Chrome processes before opening one with --js-flags. Now gc() seems to work. The 'Collect Garbage' button also works. Thanks, you've helped a lot.翻译:原来在打开带有 --js-flags 参数的 Chrome 浏览器之前,需要先关闭所有当前正在运行的 Chrome 浏览器进程。现在 gc() 函数似乎可以正常工作了,"收集垃圾" 按钮也能用了。谢谢你,你帮了很大的忙。 - Paulius K.
2
有没有办法从JavaScript中调用函数? - Saurabh Agrawal
在你不拥有相关网站的情况下,但你可以控制客户端时,你可以安装一个扩展程序,当出现“Aw Snap”错误时自动重新加载页面。一个例子是“Oh No You Didn't”扩展程序。显然,这是最后的应急方案,但它对于一些罕见的用例可能会有用 :) - Rens Tillmann

43
在Chrome开发者工具中,进入"性能"选项卡,找到一个看起来像垃圾桶的按钮。点击它将强制运行垃圾回收器。 enter image description here 注意: Chrome 53左右的旧版本中,这个按钮在"时间轴"部分,如下图所示: enter image description here

15
新版本已将“回收垃圾”按钮移至开发者工具中的“性能”选项卡中:https://i.stack.imgur.com/tguqy.png - Luiz
是的,您可以随时按下它,而且无论何时都可以。 - Nisim Joseph
1
我相信在最新版本的Chrome中,垃圾桶按钮现在已经添加到内存部分,靠近记录按钮。 - aug
1
在我的电脑上,性能和内存选项卡中似乎都有一个。 - SamB

5
我找到了一个解决方案。显然,Chrome泄露DOM节点,至少在当前版本(目前为26.0.1410.65)中是如此。
我记录了我的应用程序中的开发工具时间轴,并显示事件侦听器计数与我的应用程序屏幕内容一起节奏地上下波动,但DOM节点计数随着时间的推移稳步增加,直到选项卡崩溃。
我尝试了最新的Chrome Canary(28.0.1500.3),它们似乎已经解决了这个问题。DOM节点计数图现在遵循与事件侦听器相同的节奏模式。
让我困惑的是……为什么Gmail从不崩溃?我通常会将选项卡保持打开几周……

1
好的,至少他们修复了它。迟到总比没有好:) 感谢更新。 - Paulius K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接