JavaFX GUI不会释放内存

时间:2014-07-15 16:02:53

标签: java memory memory-management memory-leaks javafx

我几周来一直在努力解决JavaFX应用程序中的内存泄漏问题,并且认为今天我完全失去了它所以决定编写我能想到的最简单的应用程序应用程序来证明JavaFX可以在事实释放记忆,因此证明我做错了什么。令我惊讶的是,这似乎也在泄漏记忆。

任何人都可以建议为什么在单击按钮后,以下应用程序在堆中仍然有javafx.scene.control.Label?我检查它的方式是有jprofiler。

public class MemoryTestApplication extends Application {

    @Override
    public void start(Stage primaryStage) {
        //root pane
        final VBox root = new VBox();

        //label to remove when button is clicked
        final Label label = new Label("Remove Me");
        root.getChildren().add(label);

        //button to remove label
        Button btn = new Button("Remove label");
        btn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                root.getChildren().remove(label);
            }
        });
        root.getChildren().add(btn);

        //create scene and stage
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

1 个答案:

答案 0 :(得分:5)

事件处理程序的匿名内部类持有对标签的引用,并且您的按钮持有对事件处理程序的引用。

匿名内部类将由编译器创建两个合成生成的字段,如:

final Label val$label;
final MemoryTestApplication this$0;

由于这些都是最终的,因此label = null;使用它后无法清除标签,所以我认为最好的办法是将事件处理程序更改为普通的命名类,并传递标签引用到它的构造函数,然后在使用它从布局中删除标签后清除它。 (您可能希望在删除之前测试它不是null,因此只有在第一次按下按钮时才会删除它。)