*當我嘗試在JFrame中創建按鈕時,我現在遇到了一個非常奇怪的java GC問題,當我單擊該按鈕時,它顯示一個需要處理並顯示一些JDialog圖像並需要近200M內存。但問題是當我關閉對話框並重新打開它時,有時會導致java.lang.OutOfMemoryError。 (不是每一次)在對話框中收集java垃圾
試圖解決這個問題,我簡化了這個問題,並做了一些實驗,使我更加困惑的。
我在「實驗」中使用的代碼如下所示。 當我點擊一個框架中的按鈕,我分配160M內存的整數數組,並顯示一個對話框,但是,如果我關閉對話框並重新打開它,出現OutOfMemoryError。我調整的代碼和結果是:
- 如果我不創建對話框並顯示它,沒有內存問題。
- 如果我添加一個調用System.gc()到對話框的windowsCloseListener,沒有內存問題。
如果我在run()方法中調用System.gc(),則顯示內存問題。
public class TestController { int[] tmp; class TDialog extends JDialog { public TDialog() { super(); this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); // If I uncommment this code, OutOfMemoryError seems to dispear in this situation // But I'm sure it not a acceptable solution /* this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.out.println("windowsclose"); TDialog.this.dispose(); System.gc(); } }); */ } } TDialog dia; public void run() { // If I do System.gc() here, OutOfMemoryError still exist // System.gc(); 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(); controller.run(); controller = null; } }); frame.add(button); frame.setVisible(true); } }); } }
我讀過有關它描述了Java的GC工作了很多文章。我認爲如果java試圖在堆中分配一些空間並且它沒有足夠的可用空間,那麼java將會執行gc,並且如果一個對象不能通過GC graph從GC根訪問,其中一個邊你代表你有一個對v的引用,root是一個線程工作棧或本地資源中的東西,它沒有用,也沒有資格被java的GC收集。
現在的問題是當我點擊按鈕並嘗試創建一個Integer數組時,我上次創建的Integer數組肯定有資格被java的GC收集。那麼爲什麼它會導致錯誤。
道歉這麼長的描述......我沒有太多的提問策略,所以只是試圖說清楚。
此外,我用來啓動JVM的參數是「的java -Xmx256m」
1+爲您的調試努力,爲創建sscce,並努力到什麼看起來是你的問題。我沒有時間去運行或調試你的程序,但是我不知道你是否遇到了由聽衆帶來的軟引用問題。 –
如果你創建了對話框* modal *,然後在調用對話框的代碼中,通過調用'dispose()'來處理對話框。 –