TL;DR:GC 正在吞噬我的 Activity 绑定(bind)。
我有一个在 Java 7 上使用 JavaFX 2.2 开发并成功部署的应用程序。
当我升级/转换到 JavaFX 8.0(和 Java 8)时,某些功能会“神秘地”停止工作——在应用程序生命周期中——没有异常或其他错误状态变化的迹象。例如;按钮停止工作,自定义单元格渲染器停止应用,启用/禁用状态停止更新。
经过数小时的挖掘,我想我已经将问题追溯到我理解的 JavaFX 8 的一些变化以及 javafx.beans.WeakListener
的内部使用以处理内存泄漏在找到 JavaFX 2.2。基本上,我为管理数据状态依赖关系而创建的绑定(bind)似乎正在被垃圾收集,尽管它们控制的 Node
仍然处于 Activity 状态。
当我使用匿名类实例化绑定(bind)时,最常出现的问题似乎是。我的一些但不是全部的问题可以通过将绑定(bind)的引用存储为类成员来解决,从而防止 GC 收集它。我什至让整个 Controller 都被 GC 处理,因为它们是通过 FXML 加载实例化的,并且从未直接引用(我现在总是在父节点的 userData
属性中填充对 Controller 的引用)。
我的问题是:
- 相关的错误是不确定地出现的(或者至少是内存占用的函数,
- 如果应避免通过匿名类进行绑定(bind),则需要在现有的大型代码库中找到每个实例来更改它
- 即使我能找到每一个实例,代码也会变得非常困惑
令人沮丧的是,我似乎在 Oracle 文档中找不到任何内容,即“不要使用匿名类创建绑定(bind)”,或任何其他确保可靠使用绑定(bind)的准则。很多代码示例都使用匿名类绑定(bind)。我也找不到任何关于如何将 JavaFX 2.2 应用程序正确更新到 JavaFX 8 的说明。
非常感谢开发非平凡 JavaFX 应用程序的人提供的任何建议(我开发 JavaFX 2.x 应用程序已有 3 年,Swing 应用程序开发超过 15 年,所以这是t 完全是一个 n00b 问题)。
注意:我的问题类似于 Clean JavaFX property listeners and bindings (memory leaks) ,但我想具体而明确地知道如何使用复杂的绑定(bind),并确保它们不会在随机时间被垃圾收集,而不是使用对每个实例的引用来污染类。
最佳答案
WeakEventHandler -supposed- 允许对监听器对象进行 GC(如果没有以其他方式引用)并在那时停止工作。正如您所发现的,这意味着您必须引用处理程序,只要您需要它来保持触发。这个要求或多或少与你是否使用匿名类无关;如果你使用普通类,它会以同样的方式失败。
没有可能的方法来“自动”确定将来不会再触发某个事件,这本质上是“修复”此问题的功能请求所需要的。如果您不想要任何 GC,您可以简单地将所有匿名监听器添加到某个存储为静态变量的列表中。如果你希望 GC 工作(最终你会),你必须通过只在需要时维护引用并在不再需要时释放它们来控制它。
关于java - 在 JavaFX 8 中防止中间绑定(bind)被垃圾收集的推荐方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28216348/