2011-03-27 85 views
1

为什么每次按下按钮后内存使用量都增加了,因为我已经将指针设置为NULL了? (附代码)java byte array memory not released

这使得我的程序不断增加内存使用量。

谢谢。

package newHashFunction; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 

public class Memory_not_released extends JFrame{ 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     Memory_not_released memory_not_released=new Memory_not_released(); 
    } 

    Memory_not_released(){ 
     JButton button1=new JButton("create bytes"); 

     button1.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       // TODO Auto-generated method stub 
       byte[] byte1=new byte[10000000]; 
       byte1=null; 
      }}); 

     add(button1); 

     this.pack(); 
     setVisible(true); 
     this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
    } 

} 
+0

你怎么知道内存有时不会被释放?从操作系统中看到的内存使用情况应该在完整的GC之后返回,但有可能是完整的gc尚未感觉需要执行。 – Ingo 2011-03-27 11:52:20

+0

byte [] byte1 =新字节[10000000]; byte1 = null; System.gc(); 哦,它的工作原理。尽管直到第三次点击才收集,但它可以阻止我的程序耗尽内存。谢谢! – micahli123 2011-03-27 12:00:40

+0

我不太明白。但我想使用System.gc()。 – micahli123 2011-03-27 12:02:34

回答

5

将您的变量设置为null不会释放内存。内存只在垃圾收集器决定内存对于其他操作是必需的并且必须被恢复时才被释放。

即使垃圾收集器已经运行多次,完全有可能会释放内存永不

更新

我想我明白您的释放内存的关注是从哪里来的。在Java中,内存分配在堆上。无论您是否意识到,Java都配置了最大堆大小(您可以在命令行中指定此最大值)。假设Java运行的最大堆大小为100MB。现在,假设你的程序已经导致了5MB的分配。操作系统看到Java使用(大约5MB),因为这是Java在操作系统所要求的所有要求。随着程序的运行,越来越多的内存将继续分配到,直到达到最大堆大小(100MB)。在那个时候,大多数垃圾收集器在释放内存方面会更积极。在此之前,许多垃圾收集器可能根本就不打扰释放内存。

因此,您不必担心Java会占用操作系统中越来越多的内存。

+0

这很有道理。谢谢! – micahli123 2011-03-28 03:16:50

+0

如果程序超过最大堆大小,会发生什么情况?它会崩溃吗? – Kurru 2011-03-28 03:46:03

+0

@Kurru:好的,如果垃圾收集器找不到任何要释放的内存,那么你的程序会崩溃,出现java.lang.OutOfMemoryError。如果你的程序达到这样的限制,通常意味着你正在分配*巨大的*对象或者你有内存泄漏(是的,Java可能有内存泄漏)。如果问题是大量对象,那么您可以使用更大的最大堆大小重新启动Java。例如,这个命令运行一个名为'Foo'的Java类,其中包含100MB的堆:'java -Xmx100m Foo' – 2011-03-28 08:46:01

0

这是因为在垃圾收集器启动之前字节数组不会被销毁。

+0

这部分正确。你是对的,这个决定最终属于垃圾收集器。但是,如果垃圾收集器不需要,垃圾收集器可能永远不会释放该内存。 – 2011-03-27 11:53:53

+0

我只是不想深入细节。但是,当然,你说得对,GC行为完全取决于JVM。 – xappymah 2011-03-27 12:53:31

2

每按一次按钮分配10,000,000字节。将变量设置为null将允许释放这些字节,但是直到下一次垃圾收集器运行。发生这种情况可能是任意的,而且当然不是即时的。你可以尝试强制虚拟机运行垃圾回收器:

byte[] byte1=new byte[10000000]; 
byte1=null; 
System.gc(); 
+0

它的工作原理。尽管直到第三次点击才收集,但它可以阻止我的程序耗尽内存。谢谢! – micahli123 2011-03-27 12:03:24

+2

如果没有'System.gc()',请尝试一样 - 你不应该用尽内存(但你的程序可能会消耗更多的“最大堆”大小)。 – 2011-03-27 12:44:31

+0

@PaŭloEbermann我已经尝试过了。 – micahli123 2011-03-28 03:28:03