GWT垃圾回收

6

我正在创建一个新的演示者,代码如下:

new MyPresenter(new MyView());

它注册了一些事件处理程序并绑定到视图等。最终,我可能会“关闭”该视图,以便浏览器不再呈现它。我没有在任何地方维护对此MyPresenter实例的引用。
在此主题的Google论坛上,常规响应是“将您的引用设置为null”,然后无需担心它。与Javascript不同,在Java中我不能仅说this = null;,由于明显的原因。但在Javascript中,很容易将我知道不再使用的对象引用置空。
我的问题是:如何判断是否已垃圾回收此Presenter,因为我没有对它进行引用维护?它非常明显存在。我应该相信GWT和JS会处理这个问题吗?还是需要维护自己对 MyPresenter 的引用,以便在完成后手动将其设置为 null

这取决于浏览器。基本上,如果您没有引用对象,它将被收集,但是存在一些错误,例如IE中的著名错误,涉及DOM和JS对象之间的交叉引用(GWT中的默认组件通常受到保护),或者某些垃圾收集器无法删除对象岛屿。由于有很多浏览器,因此没有通用的技巧或工具可以解决此问题。唯一的选择是运行性能测试并检查内存使用情况。 - jusio
我从我的(用户)代码中从未有引用到该对象,但是它可以处理事件,因此可以证明它存在。但是,如果我删除这些事件处理程序并将"MyView"设置为null,那么是否足以使其被垃圾回收?我的担忧是它可能不够。 - Travis Webb
@TravisWebb 这应该是足够的。但是意外情况时有发生。我无法在一个评论中列出所有与GC相关的错误,但它们偶尔会发生。如果您删除对对象的所有引用,则应该被收集(添加事件侦听器之类的内容算作创建引用,因为某个对象必须知道要发送事件的位置)。 - jusio
好的。实际上,事件处理程序是一个匿名类。希望我能得到更具体的信息。 - Travis Webb
2
有关GWT处理浏览器问题的信息,请访问https://developers.google.com/web-toolkit/articles/dom_events_memory_leaks_and_you。 - fgb
值得指出的是,在JS中,“this = null”也不会有太大作用——在FF中,您会得到“无效的赋值左侧”。就像您可以在JS中将字段置为空一样,您也可以在Java中执行此操作。GWT编译的Java对象最终成为原型链接js对象,因此相同的JS垃圾回收规则应该适用于它们。 - Colin Alworth
1个回答

2
有两种内存泄漏:
  • DOM/浏览器级别的内存泄漏
  • 应用程序内存泄漏。
DOM/浏览器级别的内存泄漏通常在关闭应用程序后仍会持续存在。据我所知,只有旧版浏览器(IE6)受到影响,这就是为什么 GWT 使用一种特殊方式来附加处理程序的原因。
至少对于现代浏览器来说,这不应该是一个问题,如果您关闭应用程序,它们将成为非问题。但是它们可能会变成应用程序内存泄漏。(请参见此处以获取更多详细信息)。但总的来说,现代 JavaScript GC 在释放未使用的内存方面表现得相当出色。
长时间运行的应用程序和通过事件处理程序动态创建大量视图/Presenter 并通过引用保留可能会导致应用程序内存泄漏,但这实际上取决于涉及方的范围。
此文章是一个很好的参考,其中包含了更多信息。
最后,为了确保您真的没有任何应用程序内存泄漏,您应该使用 Dev Tools Heap Profiler 检查长时间内存消耗情况。
这篇 博客文章 有更多相关信息。

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