[英]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.