Remove Top-Level Container on Runtime

后端 未结 5 1297
深忆病人
深忆病人 2020-11-21 13:46

Unfortunately, it looks like this recently closed question was not well understood. Here is the typical output:

run:
    Trying to Remove JDialog
    Remove          


        
5条回答
  •  余生分开走
    2020-11-21 14:21

    Invoking dispose() allows the host platform to reclaim memory consumed by the heavyweight peer, but it can't do so until after the WINDOW_CLOSING event is processed on the EventQueue. Even then, gc() is a suggestion.

    Addendum: Another way to see the nightmare is via a profiler. Running the example below with jvisualvm, one can see that periodic collection never quite returns to baseline. I've exaggerated the vertical axis by starting with an artificially small heap. Additional examples are shown here. When memory is very limited, I've used two approaches:

    • Emergent: Loop from the command line, starting a new VM each time.

    • Urgent: Eliminate the heavyweight component entirely, running headless and composing in a BufferedImage using 2D graphics and lightweight components only.

    enter image description here

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.event.WindowEvent;
    import javax.swing.JDialog;
    
    /** @see https://stackoverflow.com/questions/6309407 */
    public class DialogClose extends JDialog {
    
        public DialogClose(int i) {
            this.setTitle("Dialog " + String.valueOf(i));
            this.setPreferredSize(new Dimension(320, 200));
        }
    
        private void display() {
            this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            this.pack();
            this.setLocationRelativeTo(null);
            this.setVisible(true);
            passSomeTime();
            this.setVisible(false);
            this.dispatchEvent(new WindowEvent(
                this, WindowEvent.WINDOW_CLOSING));
            this.dispose();
            passSomeTime();
        }
    
        private void passSomeTime() {
            try {
                Thread.sleep(100);
            } catch (InterruptedException ie) {
                ie.printStackTrace(System.err);
            }
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    int count = 0;
                    while (true) {
                        new DialogClose(count++).display();
                    }
                }
            });
        }
    }
    

提交回复
热议问题