java garbage collecting in dialog

前端 未结 2 1719
北恋
北恋 2021-02-09 06:49

*I\'m now encountering a very strange java GC problem when I trying to make a button in a JFrame, and when I click the button, it display a JDialog which need to deal with and s

相关标签:
2条回答
  • 2021-02-09 07:09

    You're allocating new int[40000000] before while tmp still holds the reference to the last int[40000000].
    The order of operation in an expression like tmp = new int[40000] is:

    1. new int[40000]
    2. Assign the reference to the array to tmp

    So in 1. tmp is still holding the reference to it's last value.

    Try doing:

    tmp = null;
    tmp = new int[40000000];
    
    0 讨论(0)
  • 2021-02-09 07:19

    Try this:

    import java.awt.*;
    import java.awt.event.*;
    import java.util.Random;
    import javax.swing.*;
    
    public class TestController {
       private JFrame frame;
       int[] tmp;
    
       public TestController(JFrame frame) {
          this.frame = frame;
       }
    
       public void finish() {
          if (dia != null) {
             dia.dispose();
          }
          tmp = null;
       }
    
       class TDialog extends JDialog {
          public TDialog() {
             super(frame, "Dialog", true);
             this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
          }
       }
    
       TDialog dia;
    
       public void run() {
          tmp = new int[40000000];
          for (int i = 0; i < tmp.length; i += 10)
             tmp[i] = new Random().nextInt();
          dia = new TDialog();
          dia.setVisible(true);
       }
    
       public static void main(String[] args) {
          EventQueue.invokeLater(new Runnable() {
             @Override
             public void run() {
                final JFrame frame = new JFrame("test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setSize(200, 200);
                JButton button = new JButton("button");
                button.addActionListener(new ActionListener() {
                   @Override
                   public void actionPerformed(ActionEvent e) {
                      TestController controller = new TestController(frame);
                      controller.run();
                      // controller = null;
                      System.out.println("here");
                      controller.finish();
                   }
                });
                frame.add(button);
                frame.setVisible(true);
             }
          });
       }
    }
    

    where you clean out both the dialog and its data in the finish() method. The dialog again should be modal for this to work, else you'll need a WindowListener.


    You state in comment:

    But would you tell me what's wrong in my code? and what's the meaning of "be modal". I've read the api of Dialog's setModal method in java doc. it means " whether dialog blocks input to other windows when shown", seems not the same thing as you referred.

    A modal dialog is in fact one that blocks input from the calling window, and in fact freezes code flow from the calling code as soon as the dialog is visible. Code then resumes once the dialog is no longer visible.

    There's no magical solution to your problem with the dialog being modal per se, but it allows us to know exactly when the dialog is no longer visible -- the code resumes from where the dialog was set visible, and thus allows us to call clean-up code at this point. Here I call the finish() method.

    If you don't want the dialog to be modal, then you'd need a WindowListener and listen for the dialog being closed, and then do your finish method call there.

    All my code does is make sure that the int array is available for GC'ing before you create a new int array.

    0 讨论(0)
提交回复
热议问题