【发布时间】:2017-03-05 05:20:46
【问题描述】:
我知道关于非静态内部类的内存泄漏的问题之前已经被问过。我阅读了this 和this 的问题,但我不完全明白我做错了什么。
我的班级如下
public class AddNewProductDialog {
private static AddNewProductDialog dialog;
private TextInputDialog newProductName = new TextInputDialog();
private AddNewProductDialog(){
}
public static AddNewProductDialog getInstance(){
if(dialog == null){
dialog = new AddNewProductDialog();
}
return dialog;
}
/*Helper Class start*/
private class AddNewProductDialogHelper{
private void initializeDialog(){ //---> Prepare a dialog box
newProductName.setTitle("Add New Product");
newProductName.setHeaderText("Note: This product name will be used as bat script file name. Eg. call_<productname>_script");
newProductName.setContentText("Product Name :");
newProductName.getDialogPane().lookupButton(ButtonType.OK).setDisable(true);
/*Something over here*/
newProductName.getEditor().textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
// TODO Auto-generated method stub
if(isInputvalid(newProductName.getEditor().getText())){
newProductName.getDialogPane().lookupButton(ButtonType.OK).setDisable(false);
}
}
});
}
private boolean isInputvalid(String text){
if(text.trim().length() > 0)
return true;
return false;
}
}
/*Helper class end*/
public AddNewProductDialog build(){
new AddNewProductDialogHelper().initializeDialog();
return this;
}
public void show() {
Optional<String> result = newProductName.showAndWait();
if(result.isPresent()){
//----> handle the input
}
}
}
AddNewProductDialog(外部)类是一个单例类,它有一个辅助类AddNewProductDialogHelper。这个帮助类设置TextInputDialog newProductName的属性
我调用AddNewProductDialog 类的build 方法,然后调用show 方法作为AddNewProductDialog.getInstance().build().show() 每次单击按钮 以获取用户输入。
我希望 AddNewProductDialogHelper 的实例在完成初始化 newProductName dialog box 后被垃圾回收
问题是,AddNewProductDialogHelper 的实例在堆内存中堆积并且没有被垃圾收集。每次我单击按钮以获取用户输入时,都会创建一个新实例,并且在单击按钮时它会不断堆积
然而,当我评论这个代码块时
newProductName.getEditor().textProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
// TODO Auto-generated method stub
if(isInputvalid(newProductName.getEditor().getText())){
newProductName.getDialogPane().lookupButton(ButtonType.OK).setDisable(false);
}
}
});
它可以工作,之前的实例正在被垃圾收集。 为什么注释此代码块有效?
我正在使用VisualVM 检查我的堆转储
【问题讨论】:
-
isInputValid是您的助手的方法,然后在侦听器的关闭中。
标签: java javafx memory-leaks garbage-collection