[英]java-private inner class instances not getting garbage collected
我知道关于非静态内部类的内存泄漏的问题已经有人提出过。 我读过这个和这个问题,但我不完全了解我在做什么错。
我的课如下
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检查我的堆转储
您正在将这些内部对象作为侦听器添加到侦听器列表。
因此,有对他们的参考。
因此,我认为问题不在您声称会引起麻烦的部分,而是上面的行。 只要您不以某种方式从该侦听器列表中删除内部对象,就无法对其进行垃圾收集。
因此解决方案可能很复杂:您应该退后一步并更改您的方法...您需要能够记住这些内部对象,以便可以在某个时候注销它们。
除此之外:奇怪的设计。 看起来也很难为我测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.