包含textField的JavaFX 2对象永远不会被垃圾收集器清除

时间:2012-03-06 13:25:04

标签: java garbage-collection javafx-2

还有其他人遇到过这个吗?这种情况发生在:

  • 对象A包含textField(或textArea)B。
  • 我在A的构造函数中使用了B.setOnKeyPressed来处理在B中按下某个键时的内容。
  • 之后,当A完成其功能并超出范围时,垃圾收集器将不会将其删除。

如果A不包含B,或者我没有使用B.setOnKeyPressed,或者B从未获得焦点,则不会发生这种情况。当需要使用A类的许多对象然后丢弃时,这会导致内存泄漏(只有它们不被丢弃!)

任何想法如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

没有代码很难确定,但似乎是正确的行为。

您现场有TextField B。在A的构造函数中,您创建了一个匿名类,我们将其命名为A$onKeyPressed。 Java中的匿名类不是静态的,因此这个类会引用A对象。

完成结构后,你有链接

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

因此A对GC无效。

为避免这种情况,您可以创建命名的静态内部类,并在构造函数中使用。 E.g:

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

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

答案 1 :(得分:0)

最后,我确实通过做两件事来找到解决方法:

  1. 当A超出范围时删除侦听器,通过:B.setOnKeyPressed(null);
  2. 通过C.getChildren()从其父节点C中删除B. remove(B);
  3. 这允许垃圾收集器回收A.但请注意,(1)或(2)本身并不起作用。两者都必须使用。