Javascript 在Google Chrome中强制垃圾收集

Javascript 在Google Chrome中强制垃圾收集,javascript,google-chrome,garbage-collection,zk,Javascript,Google Chrome,Garbage Collection,Zk,我们正在开发一个单页web应用程序,它可以不断与服务器通信并更新部分屏幕。更新的频率可以达到1秒。在这些更新过程中,对大量JS对象的引用丢失,这些对象最终必须由垃圾收集器清理 据我们所知,Chrome只在非活动选项卡上运行垃圾收集器。这对我们来说是个问题,因为应用程序的选项卡通常处于活动状态,几乎从不刷新,因此JS对象永远不会被收集。如果保持活动状态足够长的时间,该选项卡最终会崩溃(Aww Snap消息) 我们需要手动启动垃圾收集。到目前为止,我们已经尝试使用--js flags=“--expo

我们正在开发一个单页web应用程序,它可以不断与服务器通信并更新部分屏幕。更新的频率可以达到1秒。在这些更新过程中,对大量JS对象的引用丢失,这些对象最终必须由垃圾收集器清理

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

我们需要手动启动垃圾收集。到目前为止,我们已经尝试使用
--js flags=“--expose gc”
运行Chrome并运行
gc()
,但它引发了一个异常:

ReferenceError: gc is not defined
这在Firefox上不会发生——内存使用或多或少是一个常量

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

如有任何建议,我们将不胜感激


编辑:我们已经尝试在Chrome版本
23.0.1271.97 m
25.0.1364.2 dev-m
上运行
window.gc()
gc()
,您可以获取Chrome开发工具的代码,对其进行修改,以便
ProfilerAgent.collectGarbage()不时被调用(当您单击时间轴面板上的“收集垃圾”按钮时会调用该代码),并使用
--debug DevTools frontend
标志使用您的DevTools版本运行Chrome

然而,这个解决方案是非常极端的,只有当你真的感到绝望时才尝试它。在此之前,我建议分析您的应用程序,并检查v8决定不清理垃圾(或无法清理垃圾)的原因。DevTools的Timeline面板将帮助您解决这个问题。首先检查这个面板底部的“收集垃圾”按钮是否真的起作用,如果不起作用的话——您可能有内存泄漏(至少,根据v8)。如果是,试试看


[EDIT]我删除了有关chrome扩展的信息,因为当使用
--js flags=“--expose gc”
时,可以从网页代码中调用
gc()
。至少在我的23.0.1271.64上,我找到了一个解决方案。显然,Chrome泄露了DOM节点,至少在当前版本中是这样(现在是26.0.1410.65)

我在我的应用程序中记录了dev tools timeline,它显示事件侦听器计数随着我的应用程序屏幕的内容有节奏地上升和下降,但DOM节点计数随着时间的推移稳步增加,直到选项卡崩溃

我尝试了最新的Chrome Canary(28.0.1500.3),他们似乎已经解决了这个问题。DOM节点计数图现在遵循与事件侦听器相同的节奏模式


让我着迷的是…为什么gmail从来没有崩溃过?我通常一次打开一个标签几个星期…

在Chrome开发者工具中,你有“时间线”部分,大约是Chrome 53。你们有一个看起来像垃圾桶的按钮。单击它,它将强制垃圾收集器运行。

更新:

在较新版本的Chrome中,GC按钮移动到性能选项卡。

“据我们所知,Chrome只在非活动选项卡上运行垃圾收集器”不,这是不正确的。Chrome会在任何需要的时候运行GC,无论该选项卡是否处于活动状态。它是window.GC(),但它不是最终的解决方案,因为它只能在Chrome的调试版本上运行。正如Crowder指出的,Chrome会在需要时运行它,所以如果你的应用程序内存泄漏,那么你应该检查你的代码,以便尽可能明确地释放分配的对象。@Cerbrus:
delete
与JavaScript中的内存管理无关,除非纯粹是一种副作用,如果你碰巧用它来删除一个属性,而这个属性是对一个对象唯一未完成的引用。@Cerbrus::-)只是为了避免继续被预先设定的神话(哇,布伦丹应该称它为
删除
或什么的,但是,嘿,他承受着巨大的时间压力…)@T.J.Crowder:我们在中发现了一个问题,用户还声称,除非选项卡处于非活动状态,否则GC不会发生(第7条评论)。它被解析为WontFix。它很可能会像您描述的那样工作,但由于某些原因,它不能工作。事实证明,在打开带有
--js标志的Chrome进程之前,您必须关闭所有当前的Chrome进程。现在,
gc()
似乎起作用了。“收集垃圾”按钮也可以工作。谢谢,你帮了大忙。有没有办法从javascript调用?好吧,至少他们已经解决了。更新比不更新好:)感谢更新。较新版本已将“收集垃圾”按钮移动到“开发人员工具”中的“性能”选项卡:是。你想按多少就按多少。我相信最新的Chrome,这个垃圾按钮现在被添加到记录按钮旁边的内存部分。在我的内存中,性能和内存选项卡中似乎都有一个。