TL;DR:GC正在吞噬我的活动绑定。
我有一个应用程序,它是使用Java2.2在Java7上开发并成功部署的。
当我升级/转换到Java8.0(和JavaFX 8)时,某些特性将“神秘地”停止工作--在应用程序生命周期中期--没有异常或其他错误状态变化的迹象。例如,按钮停止工作,自定义单元格渲染器停止应用,启用/禁用状态停止更新。
经过几个小时的挖掘,我想我已经追踪到了我所理解的JavaFX 8的一些变化和javafx.beans.WeakListener
的内部使用,以处理found JavaFX 2.2中的内存泄漏。基本上,我创建的用于管理数据状态依赖项的绑定似乎正在被垃圾回收,尽管它们控制的Node
仍然处于活动状态。
最常见的问题似乎出现在我使用匿名类实例化绑定时。我的一些问题(但不是所有问题)可以通过将对绑定的引用存储为类成员来修复,从而防止GC收集它。我甚至让整个控制器都被GC了,因为它们是通过FXML加载实例化的,从来没有直接引用过(我现在总是在父节点的userData
属性中填充对控制器的引用)。
我的问题是:
令人沮丧的是,我似乎在Oracle文档中找不到任何“不要使用匿名类创建绑定”的内容,也找不到任何其他确保可靠使用绑定的指南。很多代码示例都使用了匿名类绑定。我也找不到任何关于如何正确地将JavaFX 2.2应用程序更新到JavaFX 8的说明。
我非常感谢那些开发非平凡的JavaFX应用程序的人给我的任何建议(我已经开发JavaFX 2.x应用程序3年了,开发Swing应用程序超过15年了,所以这不是n00b的问题)。
注意:我的问题类似于Clean JavaFX property listeners and bindings (memory leaks),但我想明确地知道如何使用复杂的绑定,并确保它们不会在随机时间被垃圾收集,而不是求助于引用每个实例的污染类。
发布于 2015-03-09 08:53:35
WeakEventHandler应该允许侦听器对象的GC (如果它没有被引用),并在那时停止工作。正如您已经发现的,这意味着只要您需要它来保持触发,您就必须引用该处理程序。这个要求或多或少与您是否使用匿名类无关;如果您使用普通类,它也会以同样的方式失败。
没有可能的方法来“自动”确定将来不再触发某个事件,这本质上是“修复”此问题的功能请求所需要的。如果您不想要任何GC,您可以简单地将所有匿名侦听器添加到一个列表中,作为静态变量存储在某个地方。如果你想让GC工作(最终你会工作的),你将不得不控制它,只在需要的时候维护引用,在不再需要的时候释放它们。
https://stackoverflow.com/questions/28216348
复制相似问题