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