简体   繁体   English

java-private内部类实例未获取垃圾

[英]java-private inner class instances not getting garbage collected

I know questions regarding memory leak for non-static inner classes have already been asked before. 我知道关于非静态内部类的内存泄漏的问题已经有人提出过。 I read questions this and this but I don't fully understand what wrong am I doing. 我读过这个这个问题,但我不完全了解我在做什么错。

My class is as below 我的课如下

    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
            }
        }
    }

The AddNewProductDialog (outer) class is a singleton class which has a helper class AddNewProductDialogHelper . AddNewProductDialog (外部)类是一个单例类,具有帮助器类AddNewProductDialogHelper This helper class sets the properties of TextInputDialog newProductName 该帮助器类设置TextInputDialog newProductName的属性。

I am calling the build method of class AddNewProductDialog followed by show method as AddNewProductDialog.getInstance().build().show() everytime a button is clicked to take user input. 每次单击按钮以接受用户输入时,我将调用AddNewProductDialog类的build方法,然后将其show方法称为AddNewProductDialog.getInstance().build().show()

I want the instance of the AddNewProductDialogHelper to be garbage collected after it is done initializing newProductName dialog box 我想的实例AddNewProductDialogHelper它完成初始化后,收集垃圾newProductName dialog box

The problem is that, the instances of AddNewProductDialogHelper are pilling up in Heap memory and are not getting garbage collected. 问题在于, AddNewProductDialogHelper的实例正在堆内存中堆积,并且没有得到垃圾回收。 Everytime I click the button to get user input a new instance is getting created and it keeps on pilling up as the button is clicked 每次我单击按钮获取用户输入时,都会创建一个新实例,并且在单击该按钮时它会不断堆积

However , when I comment this code block 但是 ,当我注释此代码块时

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);
                    }
                }
            });

it works and previous instances are getting garbage collected. 它可以正常工作,并且以前的实例正在收集垃圾。 Why does commenting this code block works? 为什么注释此代码块有效?

I am using VisualVM to check my heap dump 我正在使用VisualVM检查我的堆转储

You are adding those inner objects as listeners to a listener list. 您正在将这些内部对象作为侦听器添加到侦听器列表。

Thus there is a reference kept to them. 因此,有对他们的参考。

So I think the problem is not in the section that you claim to cause trouble, but the line above. 因此,我认为问题不在您声称会引起麻烦的部分,而是上面的行。 As long as you don't somehow remove the inner objects from that listener list they can't be garbage collected. 只要您不以某种方式从该侦听器列表中删除内部对象,就无法对其进行垃圾收集。

So the solution is probably complicated: you should step back and change your approach... You need to be able to remember these inner objects so that you can unregister them at some point. 因此解决方案可能很复杂:您应该退后一步并更改您的方法...您需要能够记住这些内部对象,以便可以在某个时候注销它们。

And beyond that: strange design. 除此之外:奇怪的设计。 Also looks hard to test for me. 看起来也很难为我测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM