2011-06-10 82 views
17

不幸的是,它看起来像最近关闭的question不是很好理解。这里是典型的输出:在运行时删除顶层容器

run: 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
    Will Try Remove Dialog again, CycleNo. 1 
----------------------------------------------------------- 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
    Will Try Remove Dialog again, CycleNo. 2 
----------------------------------------------------------- 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
    Will Try Remove Dialog again, CycleNo. 3 
----------------------------------------------------------- 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
*** End of Cycle Without Success, Exit App *** 
BUILD SUCCESSFUL (total time: 13 seconds) 

我再试一次问这个问题:我如何能K上运行升* L第一开顶级Container,并与收我一个帮助Swing NightMares的?

import java.awt.*; 
import java.awt.event.WindowEvent; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 

public class RemoveDialogOnRuntime extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private int contID = 1; 
    private boolean runProcess; 
    private int top = 20; 
    private int left = 20; 
    private int maxLoop = 0; 

    public RemoveDialogOnRuntime() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setPreferredSize(new Dimension(300, 300)); 
     setTitle("Remove Dialog On Runtime"); 
     setLocation(150, 150); 
     pack(); 
     setVisible(true); 
     Point loc = this.getLocation(); 
     top += loc.x; 
     left += loc.y; 
     AddNewDialog(); 
    } 

    private void AddNewDialog() { 
     DialogRemove firstDialog = new DialogRemove(); 
     remWins(); 
    } 

    private void remWins() { 
     runProcess = true; 
     Thread th = new Thread(new RemTask()); 
     th.setDaemon(false); 
     th.setPriority(Thread.MIN_PRIORITY); 
     th.start(); 
    } 

    private class RemTask implements Runnable { 

     @Override 
     public void run() { 
      while (runProcess) { 
       Window[] wins = Window.getWindows(); 
       for (int i = 0; i < wins.length; i++) { 
        if (wins[i] instanceof JDialog) { 
         System.out.println(" Trying to Remove JDialog"); 
         wins[i].setVisible(false); 
         wins[i].dispose(); 
         WindowEvent windowClosing = new WindowEvent(wins[i], WindowEvent.WINDOW_CLOSING); 
         wins[i].dispatchEvent(windowClosing); 
         Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowClosing); 
         Runtime runtime = Runtime.getRuntime(); 
         runtime.gc(); 
         runtime.runFinalization(); 
        } 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException ex) { 
         Logger.getLogger(RemoveDialogOnRuntime.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
       wins = null; 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         System.out.println(" Remove Cycle Done :-)"); 
         Runtime.getRuntime().runFinalization(); 
         Runtime.getRuntime().gc(); 
         runProcess = false; 
        } 
       }); 
      } 
      pastRemWins(); 
     } 
    } 

    private void pastRemWins() { 
     System.out.println(" Checking if still exists any of TopLayoutContainers"); 
     Window[] wins = Window.getWindows(); 
     for (int i = 0; i < wins.length; i++) { 
      if (wins[i] instanceof JFrame) { 
       System.out.println("JFrame"); 
       wins[i].setVisible(true); 
      } else if (wins[i] instanceof JDialog) { 
       System.out.println("JDialog"); 
       wins[i].setVisible(true); 
      } 
     } 
     if (wins.length > 1) { 
      wins = null; 
      maxLoop++; 
      if (maxLoop <= 3) { 
       System.out.println(" Will Try Remove Dialog again, CycleNo. " + maxLoop); 
       System.out.println(" -----------------------------------------------------------"); 
       remWins(); 
      } else { 
       System.out.println(" -----------------------------------------------------------"); 
       System.out.println("*** End of Cycle Without Success, Exit App ***"); 
       closeMe(); 
      } 
     } 
    } 

    private void closeMe() { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       System.exit(0); 
      } 
     }); 
    } 

    private class DialogRemove extends JDialog { 

     private static final long serialVersionUID = 1L; 

     DialogRemove(final Frame parent) { 
      super(parent, "SecondDialog " + (contID++)); 
      setLocation(top, left); 
      top += 20; 
      left += 20; 
      setPreferredSize(new Dimension(200, 200)); 
      setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
      setModalityType(Dialog.ModalityType.MODELESS); 
      pack(); 
      setVisible(true); 
     } 

     private DialogRemove() { 
      setTitle("SecondDialog " + (contID++)); 
      setLocation(top, left); 
      top += 20; 
      left += 20; 
      setPreferredSize(new Dimension(200, 200)); 
      setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
      setModalityType(Dialog.ModalityType.MODELESS); 
      pack(); 
      setVisible(true); 
     } 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       RemoveDialogOnRuntime superConstructor = new RemoveDialogOnRuntime(); 
      } 
     }); 
    } 
} 
+0

@mKorbel,正如我前面所说,设置为null的引用,那么它将有资格进行垃圾回收。 – mre 2011-06-10 16:44:05

+0

@mre :-)我真的很感激你在我以前的帖子中删除对Array的引用的输入,并尝试从Class中移除Object,但仍然存在一个JDialog和一个JWindow ...:-) – mKorbel 2011-06-10 16:45:14

+0

@mre我不能设置任何引用空值只有两次胜=空; – mKorbel 2011-06-10 16:49:17

回答

19

调用dispose()允许主机平台回收在重量级同行所消耗的内存,但它不能这样做,直到后的EventQueue被处理WINDOW_CLOSING事件。即使如此,gc()是一个建议。

附录:另一种通过探查器查看恶梦的方法。以jvisualvm运行下面的示例,可以看到定期收集从未相当返回到基线。我从一个人为的小堆开始夸大了纵轴。其他示例显示here。当内存非常有限时,我使用了两种方法:

  • 紧急情况:从命令行循环,每次启动一个新的VM。

  • 紧急:完全消除重量级组件,运行无头和使用2D图形和轻量级组件构建BufferedImage

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

我不确定你的问题是关于“垃圾收集”还是关于如何识别可见的对话框。

无法控制垃圾回收何时完成。调用gc()方法只是一个建议。

如果您想忽略“处置”对话框,那么您可以使用isDisplayable()方法来检查其状态。

随着下面的程序,我得到了一些有趣的结果。我做的第一个改变是在对话框中添加一些组件,以便为每个对话使用更多的资源,这将增加资源被垃圾收集的机会。

在我的机器,我发现,如果我

一)创建5个对话
B)关闭对话框
三)建立5个对话

那么第5似乎是垃圾收集。

但是,如果我创建5,然后关闭然后创建1,然后关闭,它似乎不工作。底线是你不能依赖垃圾收集何时完成,所以我建议你使用isDisplayable()方法来确定如何处理。 “显示对话框”按钮将此方法用作显示输出的一部分。

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class DialogSSCCE extends JPanel 
{ 
    public static int count; 

    public DialogSSCCE() 
    { 
     JButton display = new JButton("Display Dialogs"); 
     display.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println(); 
       System.out.println("Display Dialogs"); 

       for (Window window: Window.getWindows()) 
       { 
        if (window instanceof JDialog) 
        { 
         JDialog dialog = (JDialog)window; 
         System.out.println("\t" + dialog.getTitle() + " " + dialog.isDisplayable()); 
        } 
       } 
      } 
     }); 
     add(display); 

     JButton open = new JButton("Create Dialog"); 
     open.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println(); 
       System.out.println("Create Dialog"); 

       JDialog dialog = new JDialog(); 
       dialog.getContentPane().setLayout(null); 

       for (int i = 0; i < 200; i++) 
       { 
        dialog.add(new JTextField("some text")); 
       } 

       dialog.setTitle("Dialog " + count++); 
       dialog.setLocation(count * 25, count * 25); 
       dialog.setVisible(true); 
       System.out.println("\tCreated " + dialog.getTitle()); 
      } 
     }); 
     add(open); 

     JButton close = new JButton("Close Dialogs"); 
     close.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       System.out.println(); 
       System.out.println("Close Dialogs"); 

       for (Window window: Window.getWindows()) 
       { 
        if (window instanceof JDialog) 
        { 
         JDialog dialog = (JDialog)window; 
         System.out.println("\tClosing " + dialog.getTitle()); 
         dialog.dispose(); 
        } 
       } 

       Runtime.getRuntime().gc(); 
      } 
     }); 
     add(close); 
    } 

    private static void createAndShowUI() 
    { 
     JFrame frame = new JFrame("DialogSSCCE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new DialogSSCCE()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
3

有一个在AppContext定义了一些资源,最终会被释放之前超时。这设定为5秒钟。因此,如果您等待另外五秒钟,上下文将处理(最后一个)对话框的引用。

wins = null; 
Thread.sleep(5000); 
+0

它似乎什么也没有改变,我尝试了所有可能的木偶...... :-) +1,如果你创建多个JDialog,每个都被gc杀死,首先保持活着(JWindow也一样),如果你愿意创建大量的JDialogs和JWindows,然后每个都被处理和GC'ed,但JDialogs和JWindows的第一个也一直保持活着:-),eeerrrggghhhht ... – mKorbel 2011-06-11 16:53:06

+0

@mKorbel它确实释放了我测试中的最后一个窗口,只有JFrame剩下的。再加上一个额外的隐藏框架,你不会在你的循环中打印。因此wins.length仍然是两个! – Howard 2011-06-11 17:52:35

7

的意图,吹走约EDT所有的疑虑和确认trashgod更新的建议,然后输出到控制台

run: 
7163 KB used before GC 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
405 KB used after GC 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
    Will Try Remove Dialog again, CycleNo. 1 
----------------------------------------------------------- 
3274 KB used before GC 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
403 KB used after GC 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
    Will Try Remove Dialog again, CycleNo. 2 
----------------------------------------------------------- 
3271 KB used before GC 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
406 KB used after GC 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
    Will Try Remove Dialog again, CycleNo. 3 
----------------------------------------------------------- 
3275 KB used before GC 
    Trying to Remove JDialog 
    Remove Cycle Done :-) 
403 KB used after GC 
    Checking if still exists any of TopLayoutContainers 
JFrame 
JDialog 
----------------------------------------------------------- 
*** End of Cycle Without Success, Exit App *** 
BUILD SUCCESSFUL (total time: 26 seconds) 

从代码

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.WindowEvent; 
import javax.swing.*; 

public class RemoveDialogOnRuntime extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private int contID = 1; 
    private boolean runProcess; 
    private int top = 20; 
    private int left = 20; 
    private int maxLoop = 0; 
    private javax.swing.Timer timer = null; 

    public RemoveDialogOnRuntime() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setPreferredSize(new Dimension(300, 300)); 
     setTitle("Remove Dialog On Runtime"); 
     setLocation(150, 150); 
     pack(); 
     setVisible(true); 
     Point loc = this.getLocation(); 
     top += loc.x; 
     left += loc.y; 
     AddNewDialog(); 
    } 

    private void AddNewDialog() { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       DialogRemove firstDialog = new DialogRemove(); 
       startAA(); 
      } 
     }); 
    } 

    private void startAA() { 
     timer = new javax.swing.Timer(5000, updateAA()); 
     timer.setRepeats(false); 
     timer.start(); 
    } 

    public Action updateAA() { 
     return new AbstractAction("text load action") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       timer.stop(); 
       if (SwingUtilities.isEventDispatchThread()) { 
        Runnable doRun = new Runnable() { 

         @Override 
         public void run() { 
          remWins(); 
         } 
        }; 
        SwingUtilities.invokeLater(doRun); 
       } else { 
        Runnable doRun = new Runnable() { 

         @Override 
         public void run() { 
          remWins(); 
         } 
        }; 
        SwingUtilities.invokeLater(doRun); 
       } 
      } 
     }; 
    } 

    private void remWins() { 
     Runtime runtime = Runtime.getRuntime(); 
     long total = runtime.totalMemory(); 
     long free = runtime.freeMemory(); 
     long max = runtime.maxMemory(); 
     long used = total - free; 
     System.out.println(Math.round(used/1e3) + " KB used before GC"); 
     Window[] wins = Window.getWindows(); 
     for (int i = 0; i < wins.length; i++) { 
      if (wins[i] instanceof JDialog) { 
       System.out.println(" Trying to Remove JDialog"); 
       wins[i].setVisible(false); 
       wins[i].dispose(); 
       WindowEvent windowClosing = new WindowEvent(wins[i], WindowEvent.WINDOW_CLOSING); 
       wins[i].dispatchEvent(windowClosing); 
       Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(windowClosing); 
       runtime = Runtime.getRuntime(); 
       runtime.gc(); 
       runtime.runFinalization(); 
      } 
     } 
     wins = null; 
     System.out.println(" Remove Cycle Done :-)"); 
     runtime.runFinalization(); 
     runtime.gc(); 
     runtime = Runtime.getRuntime(); 
     total = runtime.totalMemory(); 
     free = runtime.freeMemory(); 
     max = runtime.maxMemory(); 
     used = total - free; 
     System.out.println(Math.round(used/1e3) + " KB used after GC"); 
     startOO(); 
    } 

    private void startOO() { 
     timer = new javax.swing.Timer(5000, updateOO()); 
     timer.setRepeats(false); 
     timer.start(); 
    } 

    public Action updateOO() { 
     return new AbstractAction("text load action") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       timer.stop(); 
       timer.stop(); 
       if (SwingUtilities.isEventDispatchThread()) { 
        Runnable doRun = new Runnable() {//really contraproductive just dealayed 

         @Override 
         public void run() { 
          pastRemWins(); 
         } 
        }; 
        SwingUtilities.invokeLater(doRun); 
       } else { 
        Runnable doRun = new Runnable() { 

         @Override 
         public void run() { 
          pastRemWins(); 
         } 
        }; 
        SwingUtilities.invokeLater(doRun); 
       } 
      } 
     }; 
    } 

    private void pastRemWins() { 
     System.out.println(" Checking if still exists any of TopLayoutContainers"); 
     Window[] wins = Window.getWindows(); 
     for (int i = 0; i < wins.length; i++) { 
      if (wins[i] instanceof JFrame) { 
       System.out.println("JFrame"); 
       wins[i].setVisible(true); 
      } else if (wins[i] instanceof JDialog) { 
       System.out.println("JDialog"); 
       wins[i].setVisible(true); 
      } 
     } 
     if (wins.length > 1) { 
      wins = null; 
      maxLoop++; 
      if (maxLoop <= 3) { 
       System.out.println(" Will Try Remove Dialog again, CycleNo. " + maxLoop); 
       System.out.println(" -----------------------------------------------------------"); 
       remWins(); 
      } else { 
       System.out.println(" -----------------------------------------------------------"); 
       System.out.println("*** End of Cycle Without Success, Exit App ***"); 
       closeMe(); 
      } 
     } 
     startAA(); 
    } 

    private void closeMe() { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       System.exit(0); 
      } 
     }); 
    } 

    private class DialogRemove extends JDialog { 

     private static final long serialVersionUID = 1L; 

     DialogRemove(final Frame parent) { 
      super(parent, "SecondDialog " + (contID++)); 
      setLocation(top, left); 
      top += 20; 
      left += 20; 
      setPreferredSize(new Dimension(200, 200)); 
      setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
      setModalityType(Dialog.ModalityType.MODELESS); 
      pack(); 
      setVisible(true); 
     } 

     private DialogRemove() { 
      setTitle("SecondDialog " + (contID++)); 
      setLocation(top, left); 
      top += 20; 
      left += 20; 
      setPreferredSize(new Dimension(200, 200)); 
      setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
      setModalityType(Dialog.ModalityType.MODELESS); 
      pack(); 
      setVisible(true); 
     } 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       RemoveDialogOnRuntime superConstructor = new RemoveDialogOnRuntime(); 
      } 
     }); 
    } 
} 
+0

+1在JVM退出之前,重量级组件的内存不能被可靠地回收。 – trashgod 2011-06-11 23:41:30

8

我已经完全重新设计你的例如:

  • 我有simpli田间并不需要什么(setLocation(),未使用的构造......)
  • 我已经删除了再次触发重置所有窗口可见WINDOW_CLOSING事件(没用)
  • 我已删除的代码(这将防止GC代码他们)
  • 我已经使用了javax.swing.Timer代替Thread为的对话框
  • 处置我使用了一个Thread迫使GC(而不是在美国东部时间是个好主意)
  • 我已经修改了最后的成功准则检查Window.getWindows()是(不是),因为在Swing中,如果您打开一个没有父项的对话框,则会创建一个特殊的不可见框架将其用作父项(实际上用于所有无主对话框),一旦创建,该框架不能被删除。

产生的片段如下:

import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.*; 

public class RemoveDialogOnRuntime extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private boolean runProcess; 
    private int maxLoop = 0; 
    private Timer timer; 

    public RemoveDialogOnRuntime() { 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     setPreferredSize(new Dimension(300, 300)); 
     setTitle("Remove Dialog On Runtime"); 
     setLocation(150, 150); 
     pack(); 
     setVisible(true); 
     addNewDialog(); 
    } 

    private void addNewDialog() { 
     DialogRemove firstDialog = new DialogRemove(); 
     remWins(); 
    } 

    private void remWins() { 
     runProcess = true; 
     timer = new Timer(1000, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (runProcess) { 
        for (Window win: Window.getWindows()) { 
         if (win instanceof JDialog) { 
          System.out.println(" Trying to Remove JDialog"); 
          win.dispose(); 
         } 
        } 
        System.out.println(" Remove Cycle Done :-)"); 
        runProcess = false; 
        new Thread() { 
         @Override 
         public void run() { 
          try { 
           Thread.sleep(100); 
          } catch (InterruptedException e) { 
           e.printStackTrace(); 
          } 
          Runtime.getRuntime().gc(); 
         } 
        }.start(); 
       } else { 
        pastRemWins(); 
        runProcess = true; 
       } 
      } 
     }); 
     timer.setRepeats(true); 
     timer.start(); 
    } 

    private void pastRemWins() { 
     System.out.println(" Checking if still exists any of TopLayoutContainers"); 
     Window[] wins = Window.getWindows(); 
     for (int i = 0; i < wins.length; i++) { 
      if (wins[i] instanceof JFrame) { 
       System.out.println("JFrame"); 
      } else if (wins[i] instanceof JDialog) { 
       System.out.println("JDialog"); 
      } else { 
       System.out.println(wins[i].getClass().getSimpleName()); 
      } 
     } 
     // We must expect 2 windows here: this (RemoveDialogOnRuntime) and the parent of all parentless dialogs 
     if (wins.length > 2) { 
      wins = null; 
      maxLoop++; 
      if (maxLoop <= 3) { 
       System.out.println(" Will Try Remove Dialog again, CycleNo. " + maxLoop); 
       System.out.println(" -----------------------------------------------------------"); 
       remWins(); 
      } else { 
       System.out.println(" -----------------------------------------------------------"); 
       System.out.println("*** End of Cycle Without Success, Exit App ***"); 
       closeMe(); 
      } 
     } else { 
      timer.stop(); 
     } 
    } 

    private void closeMe() { 
     System.exit(0); 
    } 

    private class DialogRemove extends JDialog { 

     private static final long serialVersionUID = 1L; 

     private DialogRemove() { 
      setTitle("SecondDialog"); 
      setPreferredSize(new Dimension(200, 200)); 
      setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
      setModalityType(Dialog.ModalityType.MODELESS); 
      pack(); 
      setVisible(true); 
     } 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       RemoveDialogOnRuntime superConstructor = new RemoveDialogOnRuntime(); 
      } 
     }); 
    } 
} 

的重要结论是:

  • 无法删除的秋千,所有无主对话框父创建的隐框
  • 你不得不强制一个气相色谱的处置对话框从Window.getWindows()(这看起来像一个错误,但我认为原因是Swing保持WeakReference到所有窗口,并且此WeakReference直到GC发生时才会释放。

希望这可以给你的问题提供一个清晰和完整的答案。

+0

感谢您的宝贵意见1+,一切都很清楚,但是在删除无用方法后,您在UsedMemory级别(通过垃圾桶)从顶级容器中删除二维图形效果后,确定仍然存在另一个选项,以减少已用内存,JDialog#WINDOW_CLOSING加JDialog#removeAll ==删除RootPane :-)那么JDialog(JWindow)的内容将是半透明的:-),结果仍然保留在Java6中任何一个Top_layoput都可以删除2D图形,谢谢 – mKorbel 2011-06-16 19:27:39