2011-03-27 66 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