在 Google Chrome 中强制进行垃圾收集

我们正在开发一个带有 ZK 的单页网络应用程序,它不断与服务器通信并更新部分屏幕.更新频率可达 1 秒.在这些更新期间,对大量 JS 对象的引用会丢失,这些对象最终必须由垃圾收集器清理.

We are developing a single-page web app with ZK which constantly communicates with server and updates parts of its screens. Updating can be as frequent as 1s. During these updates, references to large ammounts of JS objects are lost and those objects have to be cleaned by garbage collector eventually.

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

As far as we've figured out, Chrome only runs its garbage collector on inactive tabs. This is a problem for us, because the app's tab is usually active and almost never refreshed, thus JS objects never get collected. If left active for enough time, the tab eventually crashes (Aww Snap message).

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

We need to initiate garbage collection manually. So far we've tried running Chrome with --js-flags="--expose-gc" and running gc(), but it throws an exception:

ReferenceError: gc is not defined

这在 Firefox 上不会发生——内存使用或多或少是一个常数.

This doesn't happen on Firefox -- memory usage is more or less a constant.

不能强制刷新页面.

我们将不胜感激.

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

EDIT: we've tried running window.gc() and gc() both on Chrome versions 23.0.1271.97 m and 25.0.1364.2 dev-m

推荐答案

你可以获取 Chrome Dev Tools 的代码,修改它,让 ProfilerAgent.collectGarbage(); 时不时地被调用(它是当您单击时间轴面板上的收集垃圾"按钮时调用的代码)并使用您的 DevTools 版本使用 --debug-devtools-frontend 标志运行 Chrome.

You can fetch code of Chrome Dev Tools, modify it so that ProfilerAgent.collectGarbage(); is called every now and then (it's a code that is called when you click 'Collect Garbage' button on the Timeline panel) and run Chrome with your version of DevTools using --debug-devtools-frontend flag.

但是,这个解决方案非常极端,只有在你真的绝望时才尝试.到那时,我建议分析您的应用程序并检查为什么 v8 决定不清理垃圾(或无法清理垃圾).DevTools 的时间线面板将帮助您解决这个问题.首先检查此面板底部的收集垃圾"按钮是否真的有效,如果没有 - 你可能有内存泄漏(至少,根据 v8).如果是这样,请尝试 leak-finder-for-javascript.

However, this solution is quite extreme, try it only when you get really desperate. Till then, I propose profiling your application and checking out why v8 decides not to clean the garbage (or can't clean the garbage). Timeline panel of DevTools will help you out with this. Start with checking if 'Collect Garbage' button at the bottom of this panel really does its job, if not - you probably have a memory leak (at least, according to v8). If so, try leak-finder-for-javascript.

[EDIT] 我删除了有关 chrome 扩展的信息,结果发现 --js-flags 时可以从网页代码中调用 gc()="--expose-gc" 被使用.至少在我的 23.0.1271.64 上.

[EDIT] I removed info about chrome extension, as it turns out that gc() can be called from webpage code when --js-flags="--expose-gc" is used. At least on my 23.0.1271.64.

相关文章