简体   繁体   English

JavaFX GUI不释放内存

[英]JavaFX GUI doesn't release memory

I've been struggling for weeks to resolve the memory leaks within our JavaFX application, and thought today I was at a complete loss with it so decided to write the simplest application application I could think of to prove JavaFX could in fact release memory and therefore proving I was doing something wrong. 我一直在努力解决JavaFX应用程序中的内存泄漏问题已经有好几个星期了,今天我以为我完全不知所措,因此决定编写我想到的最简单的应用程序来证明JavaFX实际上可以释放内存,因此证明我做错了。 To my surprise this seems to leak memory too. 令我惊讶的是,这似乎也会泄漏内存。

Can anyone advise why the following application still has a javafx.scene.control.Label in the heap after the button is clicked? 任何人都可以建议为什么单击按钮后以下应用程序在堆中仍然具有javafx.scene.control.Label吗? The way I checked it was there was with jprofiler. 我使用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);
    }
}

Your anonymous inner class for the event handler is holding a reference to the label, and your button is holding a reference to the event handler. 您的事件处理程序的匿名内部类持有对标签的引用,而您的按钮持有对事件处理程序的引用。

The anonymous inner class is going to have two synthetically generated fields, created by the compiler, like: 匿名内部类将具有由编译器创建的两个综合生成的字段,例如:

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

Since these are final, you can't clear label after using it by label = null; 由于这些都是最终的,因此在使用label = null;后,您将无法清除label label = null; , so I think your best bet is to change the event handler to a normal, named class, pass the label reference in to its constructor, and then clear it after using it to remove the label from the layout. ,所以我认为最好的选择是将事件处理程序更改为普通的命名类,将标签引用传递给其构造函数,然后在使用它从布局中删除标签后将其清除。 (You would want to test that it was not null before removing, so that it would only be removed the first time the button is pressed). (您要在删除之前测试它是否为null,以便仅在第一次按下按钮时将其删除)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM