2013-09-22 37 views
3

我已經創建了一個新的項目,用java這個簡單的代碼:JFrame的內存泄露

public static void main(String[] args) 
{ 
    JFrame frame; 
    frame = new JFrame("Empty"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setResizable(false); 
    frame.setLocationRelativeTo(null); 
    frame.setVisible(true); 
} 

我已經注意到,移動的JFrame造成使用過程中增加內存。

  1. 這是爲什麼?
  2. 有沒有辦法避免使用上面相同的代碼,但有一些補充?
  3. 有沒有更好的方法來簡單地顯示一個JFrame?
+0

一個相關的問題是還檢查在該[Q&A(http://stackoverflow.com/q/6309407/230513)。 – trashgod

回答

3

看到內存使用增加並不意味着有內存泄漏。該程序可能會使用更多的內存,因爲它必須爲事件分派或重新繪製創建臨時對象。這些臨時對象是短暫的,並在短時間內被垃圾收集器清除;所以它們使用的內存可以再次用於程序。

儘管由於內存沒有返回到操作系統,您將不會看到這與過程監視工具, JVM保留它以供將來使用。您可以使用像VisualVM這樣的工具來監視程序的實際內存使用情況。

有沒有更好的方法來簡單地顯示JFrame?

您發佈的代碼實際上是不正確的;您不應該從程序的主線程創建和操作GUI對象。下面是顯示的正確實例的JFramefrom the Java Tutorial

import javax.swing.*;   

public class HelloWorldSwing { 
    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("HelloWorldSwing"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Add the ubiquitous "Hello World" label. 
     JLabel label = new JLabel("Hello World"); 
     frame.getContentPane().add(label); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 
+0

感謝您的回答。我做了你的建議(更改代碼並使用VisualVM),我注意到堆的使用量正在增加,即使不移動JFrame。這是正常的嗎?這是[鏈接](http://oi42.tinypic.com/wjx7rm.jpg)。 –

+0

這看起來有點可疑,但由於程序有大量的空閒內存,GC可能不會費心做一個資源密集型的完整垃圾收集。如果按下「執行gc」按鈕,或者使用更小的堆運行程序的時間更長,則應該看到堆使用情況下降。 – Joni

+0

您可以安裝visualgc或內存池插件以更好地瞭解發生了什麼:您會發現最小的一代在每個小型GC上完全清除,而對象在較老的一代中緩慢堆積。較不頻繁的完整GC將從舊一代中移除物體。 – Joni