gpt4 book ai didi

java-私有(private)内部类实例没有被垃圾收集

转载 作者:行者123 更新时间:2023-12-01 08:47:13 24 4
gpt4 key购买 nike

我知道之前已经有人问过有关非静态内部类内存泄漏的问题。我读了问题thisthis但我不完全明白我做错了什么。

我的类(class)如下

    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检查我的堆转储

最佳答案

您正在将这些内部对象作为监听器添加到监听器列表中。

因此,对它们保留了引用。

所以我认为问题不在于您声称造成麻烦的部分,而在于上面的行。只要您不以某种方式从该监听器列表中删除内部对象,它们就无法被垃圾收集。

所以解决方案可能很复杂:您应该退一步并改变您的方法...您需要能够记住这些内部对象,以便您可以在某个时候取消注册它们。

除此之外:奇怪的设计。对我来说看起来也很难测试。

关于java-私有(private)内部类实例没有被垃圾收集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42604816/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com