Объекты JavaFX 2, содержащие textField, никогда не очищаются сборщиком мусора - PullRequest
1 голос
/ 06 марта 2012

Кто-нибудь еще сталкивался с этим? Это происходит, когда:

  • Объект A содержит textField (или textArea) B.
  • Я использовал B.setOnKeyPressed в конструкторе A, чтобы делать что-то, когда клавиша нажимается в B.
  • Впоследствии, когда A завершит свою функцию и выйдет из области видимости, сборщик мусора не удалит его.

Этого не происходит, если A не содержит B, или если я не использовал B.setOnKeyPressed или если B никогда не получает фокус. Это приводит к утечке памяти, когда нужно использовать множество объектов класса А, а затем выбросить их (только они не удаляются!)

Есть идеи, как обойти это?

Ответы [ 2 ]

0 голосов
/ 07 марта 2012

Наконец-то я нашел способ обойти это, сделав две вещи:

  1. удаление слушателя, когда A выходит из области видимости: B.setOnKeyPressed (null);
  2. удалить B из родительского узла C, используя C.getChildren (). Remove (B);

Это позволяет утилизировать А сборщиком мусора. Обратите внимание, что (1) или (2) одни не работают, хотя. Оба должны были быть использованы.

0 голосов
/ 06 марта 2012

Трудно быть уверенным без кода, но, похоже, это правильное поведение.

У вас есть TextField B на сцене.В конструкторе A вы создаете анонимный класс, назовем его A$onKeyPressed.Анонимные классы в Java не являются статичными, поэтому этот объект сохраняет ссылку на A объект.

После того, как contstructor готов, у вас есть ссылка

scene -> B -> onKeyPressedListeners -> A$onKeyPressed -> A 

Таким образом, A недопустимо для GC.

Чтобы избежать этого, вы можете создать именованный статический внутренний класс и использовать его в конструкторе.Например:

public class A {
    public A(TextField B) {
        B.setOnKeyPressed(new AHandler());
    }

    private static class AHandler implements EventHandler<KeyEvent> {
        public void handle(KeyEvent t) {  /* doStuff */ }
    }
}
...