2013-09-22 34 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