2010-11-08 37 views

回答

35

有一個對單例的靜態引用,所以它只有在類加載器符合垃圾回收的條件時纔可以進行垃圾回收。

你不能強制任何對象被垃圾收集;你可以請求垃圾收集器運行System.gc()但它只是一個請求。

如果你真的想讓一個「singleton」符合垃圾收集的條件,你可能想要一個方法來將靜態變量設置爲null(並且希望沒有別的東西需要引用副本)。很顯然,下一次任何人要求一個實例時,都需要重新創建......當然,這不是一個單身實例。

+0

任何解決這個問題的方法都不是使用單例模式嗎? – Julio 2010-11-08 19:55:08

+1

@Franco:你還沒有真正說出你想要達到的目標,這就很難提出解決方案。 – 2010-11-08 19:57:57

+1

+1,你已經說了我想說的實際內容。 – 2010-11-08 19:59:36

5

如果您在單例類中保留靜態引用,那麼引用計數不能降爲0,因此它不應該被收集。

+5

請注意,Java通常不通過引用計數來實現。你可能很清楚這一點,但你的答案*有點意味着計數正在進行。 – 2010-11-08 19:58:32

+0

結論是正確的,但是Java GC不能用引用計數來實現,因爲它們也必須能夠收集循環數據結構。 – Landei 2010-11-08 20:00:06

+1

@Jon:沒錯,對於對象來說總是有一個可達的引用,因此它永遠不會被認爲是垃圾。 T'是一個滑稽的手指;) – 2010-11-08 20:02:09

3

Java中有一些特殊對象稱爲GC根。它們總是可到達的,從這些根可以到達的對象也是如此。這些GC根目錄永遠不會被垃圾收集,從這些根目錄可以訪問的對象也是如此。在Java靜態變量中形成GC根。

Singleton類對實例化的單例對象有一個靜態引用,因此它永遠不會被垃圾回收,除非Jon Skeet聲明加載這個類的上下文(類加載器)本身適合垃圾收集,在這種情況下該靜態引用將不再是GC根目錄。

Relevant answer here

我認爲這是一個Java 1.2之前的錯誤,當單例實例可能被垃圾回收時,如果沒有全局引用它,但是在Java 1.2中已修復並且現在只有這樣,它可以符合垃圾回收的條件是加載這個類的類加載器被垃圾回收。

0

static字段可以並確實得到GCed然而,這不會發生在一個簡單的應用程序。

靜態字段由Class引用,Class由ClassLoader引用。 ClassLoader由每個類和該類的每個實例引用。

但是,在OSGi容器和應用程序服務器中,刪除對應用程序或庫的所有引用並且它是類加載器並不罕見。此時,類加載器和每個靜態字段都可以進行GC編輯。

相關問題