在 JavaFX 8 中防止中间绑定被垃圾收集的推荐方法是什么
What is the recommended approach to keeping intermediate bindings from being garbage collected in JavaFX 8
TL;DR:GC 正在占用我的活动绑定。
我有一个应用程序是使用 JavaFX 2.2 在 Java 7 上开发并成功部署的。
当我 upgraded/transitioned 到 JavaFX 8.0(和 Java 8)时,某些功能会 "mysteriously" 停止工作——应用程序生命周期中期——无一例外或其他错误状态变化的迹象。例如;按钮停止工作,停止应用自定义单元格渲染器,enabled/disabled 状态停止更新。
经过数小时的挖掘,我想我已经将问题追踪到我所理解的 JavaFX 8 的一些变化和 javafx.beans.WeakListener
的内部使用以处理内存泄漏在找到 JavaFX 2.2。基本上,我创建的用于管理数据状态依赖性的绑定似乎正在被垃圾收集,尽管它们控制的 Node
s 仍然处于活动状态。
当我使用匿名 classes 实例化绑定时,问题似乎最常出现。可以通过将对绑定的引用存储为 class 成员来解决我的一些但不是全部问题,从而防止 GC 收集它。我什至让整个控制器都进行了 GC,因为它们是通过 FXML 加载实例化的,并且从未直接引用过(我现在总是在父节点的 userData
属性 中填充对控制器的引用)。
我的问题是:
- 相关错误不确定地出现(或者至少是内存占用的函数,
- 如果应避免通过匿名 classes 进行绑定,则需要大量工作才能在大型现有代码库中找到每个实例以对其进行更改
- 即使我能找到每个实例,它也会使代码变得非常混乱
令人沮丧的是,我似乎无法在 Oracle 文档中找到任何说明 "don't create bindings with anonymous classes" 或任何其他确保可靠使用绑定的指南。许多代码示例 使用 匿名 class 绑定。我也找不到关于如何将 JavaFX 2.2 应用程序正确更新到 JavaFX 8 的任何说明。
开发 非平凡 JavaFX 应用程序的人的任何建议都非常感谢(我一直在开发 JavaFX 2.x 3 年的应用程序,以及超过 15 年的 Swing 应用程序,所以这不完全是一个 n00b 问题)。
注意:我的问题类似于 Clean JavaFX property listeners and bindings (memory leaks),但我想具体而明确地知道如何使用复杂绑定并确保它们不会在随机时间被垃圾回收,而不诉诸于污染 class包含对每个实例的引用。
WeakEventHandler -应该- 允许监听器对象的 GC(如果它没有以其他方式被引用)并且在那个时候简单地停止工作。正如您所发现的,这意味着只要您需要它继续触发,您就必须引用处理程序。此要求或多或少与您是否使用匿名 class 无关;如果你使用普通的 class.
它也会以同样的方式失败
无法"automatically" 确定将来不再触发某个事件,这实际上是 "fix" 此问题的功能请求所需要的。如果你不想要任何 GC,你可以简单地将所有匿名监听器添加到一个列表中,该列表作为静态变量存储在某处。如果您希望 GC 工作(最终您会的),您将必须通过仅在需要时维护引用并在不再需要时释放它们来控制它。
TL;DR:GC 正在占用我的活动绑定。
我有一个应用程序是使用 JavaFX 2.2 在 Java 7 上开发并成功部署的。
当我 upgraded/transitioned 到 JavaFX 8.0(和 Java 8)时,某些功能会 "mysteriously" 停止工作——应用程序生命周期中期——无一例外或其他错误状态变化的迹象。例如;按钮停止工作,停止应用自定义单元格渲染器,enabled/disabled 状态停止更新。
经过数小时的挖掘,我想我已经将问题追踪到我所理解的 JavaFX 8 的一些变化和 javafx.beans.WeakListener
的内部使用以处理内存泄漏在找到 JavaFX 2.2。基本上,我创建的用于管理数据状态依赖性的绑定似乎正在被垃圾收集,尽管它们控制的 Node
s 仍然处于活动状态。
当我使用匿名 classes 实例化绑定时,问题似乎最常出现。可以通过将对绑定的引用存储为 class 成员来解决我的一些但不是全部问题,从而防止 GC 收集它。我什至让整个控制器都进行了 GC,因为它们是通过 FXML 加载实例化的,并且从未直接引用过(我现在总是在父节点的 userData
属性 中填充对控制器的引用)。
我的问题是:
- 相关错误不确定地出现(或者至少是内存占用的函数,
- 如果应避免通过匿名 classes 进行绑定,则需要大量工作才能在大型现有代码库中找到每个实例以对其进行更改
- 即使我能找到每个实例,它也会使代码变得非常混乱
令人沮丧的是,我似乎无法在 Oracle 文档中找到任何说明 "don't create bindings with anonymous classes" 或任何其他确保可靠使用绑定的指南。许多代码示例 使用 匿名 class 绑定。我也找不到关于如何将 JavaFX 2.2 应用程序正确更新到 JavaFX 8 的任何说明。
开发 非平凡 JavaFX 应用程序的人的任何建议都非常感谢(我一直在开发 JavaFX 2.x 3 年的应用程序,以及超过 15 年的 Swing 应用程序,所以这不完全是一个 n00b 问题)。
注意:我的问题类似于 Clean JavaFX property listeners and bindings (memory leaks),但我想具体而明确地知道如何使用复杂绑定并确保它们不会在随机时间被垃圾回收,而不诉诸于污染 class包含对每个实例的引用。
WeakEventHandler -应该- 允许监听器对象的 GC(如果它没有以其他方式被引用)并且在那个时候简单地停止工作。正如您所发现的,这意味着只要您需要它继续触发,您就必须引用处理程序。此要求或多或少与您是否使用匿名 class 无关;如果你使用普通的 class.
它也会以同样的方式失败无法"automatically" 确定将来不再触发某个事件,这实际上是 "fix" 此问题的功能请求所需要的。如果你不想要任何 GC,你可以简单地将所有匿名监听器添加到一个列表中,该列表作为静态变量存储在某处。如果您希望 GC 工作(最终您会的),您将必须通过仅在需要时维护引用并在不再需要时释放它们来控制它。