简而言之: 垃圾回收正在清除我的活动绑定。
我有一个应用程序,使用JavaFX 2.2和Java 7成功开发和部署。
当我升级/转换到JavaFX 8.0(和Java 8)时,某些功能会在应用程序生命周期中“神秘地”停止工作,没有异常或其他指示错误状态的变化。例如:按钮停止工作,自定义单元格渲染器停止应用,启用/禁用状态停止更新。
经过多个小时的挖掘,我认为我已经追踪到了问题所在,这是由于JavaFX 8中的一些更改以及内部使用javafx.beans.WeakListener
来处理在JavaFX 2.2中发现的内存泄漏。基本上,尽管它们控制的Node
仍然处于活动状态,但我创建的管理数据状态依赖性的绑定正在被垃圾回收清除。
当我使用匿名类实例化绑定时,问题似乎最常见。我的一些问题可以通过将绑定存储为类成员的方式来修复,从而防止GC对其进行收集。我甚至曾经因为它们是通过FXML加载实例化的,从未直接引用过控制器(现在我总是将对控制器的引用塞到父节点的userData
属性中)。
我的问题是:
- 相关的错误是非确定性的(或者至少是内存占用的功能)。
- 如果应该避免使用匿名类进行绑定,则需要在大型、现有代码库中查找每个实例以进行更改,这是很繁琐的工作。
- 即使我能找到每个实例,它也会极大地混杂代码。
令人沮丧的是,我似乎找不到Oracle文档中说“不要使用匿名类创建绑定”的任何内容,或者其他确保可靠使用绑定的指导方针。许多代码示例都使用了匿名类绑定。我也找不到关于如何正确更新JavaFX 2.2应用程序到JavaFX 8的任何说明。
非常感谢那些开发复杂JavaFX应用程序的人提供的任何建议(我已经开发了3年的JavaFX 2.x应用程序,并且开发了超过15年的Swing应用程序,所以这不是一个新手问题)。注意:我的问题类似于清理JavaFX属性监听器和绑定(内存泄漏),但我想要具体而明确地知道如何使用复杂的绑定,并确保它们不会在随机时间被垃圾回收,而不必污染类与每个实例的引用。