2010-06-18 41 views
0

我需要知道Java中的垃圾收集器是獨立運行還是需要啓動它。Java中的垃圾收集器是否自動工作?

+2

自動,自己 – 2010-06-18 06:20:24

+0

你可以毫不猶豫地告訴JVM垃圾收集,但它會根據自己的工作,當它需要的資源。 – gmhk 2010-06-18 06:37:00

+1

下一個問題:-)我的垃圾沒有收集 - 爲什麼? – Blauohr 2010-06-18 07:57:49

回答

4

它可以自行工作。你可以「建議」它運行,但這就是它。

+0

如果我沒有記錯的話,從使用Sun的HotSpot虛擬機的Java 1.4開始,'System.gc();'實際上是非操作的。其他VM:可能仍然對該呼叫作出反應。 – Esko 2010-06-18 07:44:40

0

是的,垃圾回收是由Java自動處理的。 當一個對象不再被任何變量引用時,Java會自動回收該對象使用的內存。這被稱爲垃圾收集。 仍然可以使用方法 System.gc()顯式調用它。

+1

垃圾收集!=參考計數!可能有一個對象不再被引用,GC仍然沒有釋放它。儘管如此,還是有可能引用對象並進行垃圾收集。 (循環引用但無法訪問的對象) – 2010-06-18 06:41:22

2

GC是一個deamon線程,它開始於您的JVM,並在JVM結束時結束(如果沒有其他非deamon線程存在,JVM將停止運行)。

它在後臺運行並在需要時啓動。 JVM決定它何時運行,您可以「請求」它運行System.gc()

但我應該提到,你不能編寫代碼來依賴GC來運行(Java中的終結器不像C++中的析構函數)。人們往往對GC非常重視,然後忘記它是否是否定的,並導致內存泄漏並很難找到錯誤。

你可以指望的是,在你得到一個java.lang.OutOfMemoryError之前,GC鼓勵並付出了努力。

+1

你應該澄清你的第三段 - 你是對的,你不應該依賴任何**特定的** GC時序等(包括使用終結器)。但是,您的警告可能意味着您不能指望GC運行*,即您應該以某種方式自己處理舊對象,這可能會造成混淆。 – 2010-06-18 07:12:03

+0

@Andrzej Doyle:JLS不保證終結者將被執行。 GC本身可能無法運行。這發生在使用少量對象的小程序上。 JVM會停止而不會調用GC。唯一確保終結器執行的是System.runFinalizersOnExit和Runtime.runFinalizersOnExit,現在已經廢棄了一段時間。再一次,沒有什麼能保證GC能夠運行。 – 2010-06-18 09:29:31

1

它根據優化算法自行工作以獲得最佳性能。您可以執行強制垃圾回收,但不建議這樣做,因爲它可以阻止正常的垃圾回收模式,從而降低實際性能。

您應該在相關主題上閱讀this Old SO Discussion

0

(這可能只是重複什麼其他的答案是想說......不過,值得一說的這個清楚

Java垃圾收集器自動運行的需要,而且也沒有必要開始它。

有一種靜態方法(System.gc()),應用程序可以調用請求垃圾回收器運行「now」。但是:

  • 可以將JVM配置爲不關注此請求。
  • 通常是壞主意發出此請求,因爲它可以顯着降低垃圾回收器的性能。一般來說,運行垃圾收集器的最佳時機是當有大量垃圾被收集時,並且只有JVM知道這可能是什麼時候。

編輯 - 治癒大型垃圾收集延遲是改變JVM的垃圾收集器的屬性來選擇低延遲的收集器。在現代JVM中調用System.gc()並不是解決這個問題的方法。

+0

雖然我並不真的不同意你說的話,但在某些情況下,你想在有很多垃圾收集之前運行gc。大的gc運行會導致很長的延遲。在某些情況下,最好有幾個小的比一個大。 – 2010-06-18 07:44:36

+1

@Mattias:那麼你應該改變GC配置/實現,而不是依靠System.gc() – pgras 2010-06-18 08:50:16

0

我知道你必須調用System.gc()的唯一場合是當你創建大量的Direct ByteBuffers時。對於堆內存來說,OutOfMemoryError只會在完整的GC之後發生,但是對於直接內存,如果用盡(即使可能存在未被引用的緩衝區),則不會調用GC,因此您可能必須先自己調用它再試一次。

我希望這是在未來版本的Java中修復的東西。