在 JavaFX 8 中防止中间绑定被垃圾收集的推荐方法是什么

问题描述 投票:0回答:1

TL;DR:GC 正在吞噬我的活动绑定。

我有一个在 Java 7 上使用 JavaFX 2.2 开发并成功部署的应用程序。

当我升级/过渡到 JavaFX 8.0(和 Java 8)时,某些功能会“神秘地”停止工作——在应用程序生命周期中——没有异常或其他错误状态更改的迹象。例如;按钮停止工作,自定义单元格渲染器停止应用,启用/禁用状态停止更新。

经过数小时的挖掘,我想我已经将问题追踪到我所理解的 JavaFX 8 中的一些变化和

javafx.beans.WeakListener
的内部使用,以处理 JavaFX 2.2 中发现的内存泄漏。基本上,我创建的用于管理数据状态依赖性的绑定似乎正在收集垃圾,尽管它们控制的
Node
s 仍然处于活动状态。

当我使用匿名类实例化绑定时,问题似乎最常出现。我的一些但不是全部问题可以通过将绑定的引用存储为类成员来解决,从而防止 GC 收集它。我什至让整个控制器都进行了 GC,因为它们是通过 FXML 加载实例化的,并且从未直接引用过(我现在总是在父节点的

userData
属性中填充对控制器的引用)。

我的问题是:

  1. 相关的错误不确定地出现(或者至少是内存占用的函数)。
  2. 如果应避免通过匿名类进行绑定,则需要大量工作才能在大型现有代码库中找到每个实例以进行更改。
  3. 即使我能找到每个实例,它也会极大地破坏代码。

令人沮丧的是,我似乎无法在 Oracle 文档中找到任何内容“不要使用匿名类创建绑定”,或任何其他确保可靠使用绑定的指南。那里的很多代码示例use 匿名类绑定。我也找不到任何关于如何将 JavaFX 2.2 应用程序正确更新到 JavaFX 8 的说明。

非常感谢开发重要JavaFX 应用程序的人提出的任何建议(我开发 JavaFX 2.x 应用程序已有 3 年,而 Swing 应用程序已超过 15 年,所以这不完全是一个 n00b 问题)。


注意:我的问题类似于Clean JavaFX property listeners and bindings (memory leaks),但我想具体而明确地知道如何使用复杂的绑定并确保它们不会在随机时间被垃圾收集,而无需求助于污染类引用每个实例。

java javafx java-8 javafx-8
1个回答
3
投票

WeakEventHandler 应该允许监听器对象的 GC(如果它没有被引用)并且在那个时候简单地停止工作。正如您所发现的,这意味着只要您需要它继续触发,您就必须引用处理程序。此要求或多或少与您是否使用匿名类无关;如果您使用普通课程,它会以同样的方式失败。

无法“自动”确定将来不再触发某个事件,这实际上是“修复”此问题的功能请求所需要的。如果你不想要任何 GC,你可以简单地将所有匿名监听器添加到一个列表中,该列表作为静态变量存储在某处。如果你想让 GC 工作(最终你会的),你将不得不通过仅在需要时维护引用并在不再需要时释放它们来控制它。

© www.soinside.com 2019 - 2024. All rights reserved.