Подтвердить что ты не робот

Каков рекомендуемый подход для хранения промежуточных привязок от сбора мусора в JavaFX 8

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 (утечки памяти), но я хочу знать конкретно и окончательно, как использовать сложные привязки и обеспечивать они не будут собирать мусор в произвольные моменты времени, не прибегая к загрязняющим классам со ссылками на каждый экземпляр.

4b9b3361

Ответ 1

The WeakEventHandler -supposed - разрешить GC объекта слушателя (если он не упоминается иначе) и просто перестать работать в это время. Как вы обнаружили, это означает, что вам нужно ссылаться на обработчик, если он вам нужен, чтобы продолжать запуск. Это требование более или менее независимо от того, используете ли вы анонимный класс или нет; он будет работать не так, как если бы вы использовали обычный класс.

Невозможно "автоматически" определить, что определенное событие больше не будет запущено в будущем, что, по сути, требует запрос функции "исправить" эту проблему. Если вы не хотите ничего GC'd, вы можете просто добавить всех анонимных слушателей в список, который хранится как статическая переменная где-нибудь. Если вы хотите, чтобы GC работал (и в конце концов вы это сделаете), вам придется управлять им, поддерживая ссылки только тогда, когда они нужны, и освобождая их, когда их больше нет.