我几周来一直在努力解决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);
}
}
答案 0 :(得分:5)
事件处理程序的匿名内部类持有对标签的引用,并且您的按钮持有对事件处理程序的引用。
匿名内部类将由编译器创建两个合成生成的字段,如:
final Label val$label;
final MemoryTestApplication this$0;
由于这些都是最终的,因此label = null;
使用它后无法清除标签,所以我认为最好的办法是将事件处理程序更改为普通的命名类,并传递标签引用到它的构造函数,然后在使用它从布局中删除标签后清除它。 (您可能希望在删除之前测试它不是null,因此只有在第一次按下按钮时才会删除它。)