TL; DR: GC ест мои активные привязки.
У меня есть приложение, которое было разработано и успешно развернуто с использованием JavaFX 2.2 на Java 7.
Когда я обновил/перешел на JavaFX 8.0 (и Java 8), некоторые функции "таинственно" перестали бы работать - средний жизненный цикл приложения - без каких-либо исключений или других признаков ошибочного изменения состояния. Например; кнопки перестают работать, пользовательские рендеринги ячеек перестают применяться, состояние включено/отключено перестает получать обновления.
После многих часов копания, я думаю, что я отследил проблему до того, что, как я понимаю, было некоторыми изменениями в JavaFX 8 и внутренним использованием javafx.beans.WeakListener
для устранения утечек памяти в найденном JavaFX 2.2. Похоже, что привязки, которые я создаю для управления зависимостью данных, получают сбор мусора, несмотря на то, что элементы управления Node
все еще активны.
Проблемы, которые чаще всего возникают, возникают при создании привязок с использованием анонимных классов. Некоторые, но не все мои проблемы могут быть исправлены путем хранения ссылки на привязку в качестве члена класса, тем самым удерживая GC от ее сбора. У меня даже были все контроллеры получить GC'd, потому что они были созданы через загрузку FXML и никогда не ссылались напрямую (теперь я всегда ссылаюсь на контроллер в родительском свойстве node userData
).
Мои проблемы:
- связанные ошибки возникают недетерминистически (или, по крайней мере, являются функцией памяти,
- если нужно избегать привязок, хотя следует избегать анонимных классов, очень много работы, чтобы найти каждый экземпляр в большой существующей базе кода, чтобы изменить его.
- даже если бы я мог найти каждый экземпляр, он сильно загромождает код
Разочарочно, я не могу найти ничего в документации Oracle, в которой говорится: "Не создавайте привязки с анонимными классами" или какие-либо другие рекомендации для обеспечения надежного использования привязок. Многие примеры кода используют анонимные привязки классов. Я также не могу найти заметки о том, как правильно обновлять приложение JavaFX 2.2 для JavaFX 8.
Любые советы от людей, разрабатывающих нетривиальные приложения JavaFX, очень ценятся (я разрабатываю приложения JavaFX 2.x уже 3 года, а приложения для Swing - более 15 лет, так что это не совсем вопрос n00b).
Примечание. Мой вопрос похож на Очистить слушатели свойств и привязки JavaFX (утечки памяти), но я хочу знать конкретно и окончательно, как использовать сложные привязки и обеспечивать они не будут собирать мусор в произвольные моменты времени, не прибегая к загрязняющим классам со ссылками на каждый экземпляр.