簡體   English   中英

java-private內部類實例未獲取垃圾

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM