2011-06-10 81 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