2012-05-14 18 views
3

我在Java中知道我們有軟參考的概念。如果:如果存在兩級軟參考對象,GC會做什麼

1)有一個軟引用 「SF」 是指一個物體A

2)在對象A,它具有很強的參考指的是對象B

3)對象A & B在其他地方沒有引用。

根據定義,對象A和對象B都是「輕度可達」的,對吧?

然後說我們現在內存不足了,GC開始了。有沒有可能GC會回收對象B但不是對象A?

如果是這種情況,稍後如果我們想通過「sf」訪問對象B,它將爲空。 Java如何避免這種情況發生?

我在java文檔中看不到任何解釋。

+1

我認爲GC既可以收集A和B,也可以不收集它們,因爲它是合乎邏輯的,但這只是猜測。 – Jeffrey

回答

6

然後說我們現在內存不足了,GC開始了。是否有可能GC會回收對象B但不是對象A?

不可以.GC不會破壞可到達對象中的強引用。 (當然,它將在不可恢復的對象中引用作爲回收過程的一部分,但是你無法觀察到這種情況......因爲要觀察它,你需要該對象仍然可以到達。)

這是在javadoc for java.lang.ref包中的這個聲明的結果。

「最後,無法訪問對象時,因此符合回收條件,但無法通過上述任何方式到達。」

......其中「上述方式」包括強,弱,弱和幻象可達性。

兩個突出顯示的詞語意味着回收資格是處於不可達狀態的結果。由於沒有其他州提及填海資格,我們認爲不可達性是填海工程的先決條件。

這當然符合常識。如果(假設)允許GC在可到達對象中「強制」引用強引用,那麼應用程序在進入此狀態後就不可能安全地使用對象。 (考慮這樣調零出參照的是在一個庫類的一個實例的情況下...)

+0

你有一個來源說明這一點? – Jeffrey

+0

@Jeffrey:它會徹底打破語言語義。如果任何外部部分使用WeakReference,那麼在程序的任何部分中的任何引用都可能隨意在任何時候任意變爲空,原因不明。這將是可怕的! –

+0

@StevenSchlansker這不會影響我的程序的任何部分的任何引用,只輕聲或弱可及的。 – Jeffrey

1

從文檔:

「的對象是軟可到達,如果它不是強可到達,但可以達到通過遍歷一個軟參考。「

「的對象是強可如果它可以通過一些線索,而無需遍歷任何參考對象達」

我認爲是很清楚。 B可以輕鬆訪問,因爲它只能通過遍歷軟引用來訪問。

Said Docs

+0

我知道這一點。但我想知道我的第二個更重要的問題的答案。 – performanceuser

+0

不要使用SoftReference。將引用存儲在強引用的緩存中。 A將被收集。因爲圖形向下遍歷。沒有什麼能阻止你收集A,因爲它引用B – nsfyn55

+0

我不想擺脫這個問題。我想了解GC如何工作 – performanceuser

2

我想追查選區如何的基本工作原理應該明確的事情了一個簡短的介紹。

跟蹤GC(在Java和.NET中使用的GC都屬於該類別)有一組所謂的root pointers,它們是全局變量(在java中表示類的靜態變量)以及所有活動變量stackframes。 GC遍歷它們並標記所有活動的對象,即通過至少一個根指針引用可訪問。完成後,所有活動變量都已標記,剩下的可以被垃圾收集。一)我們按照軟引用和標記中的所有對象或b)我們不這樣做:

軟引用現在可以在兩種不同的方式來處理。究竟發生了什麼是在給定的JVM實現的擺佈,但在此之後已經決定了沒有其他區別。

因此,有兩種可能的情況:

  • 的GC如下軟引用至其中包括兩個對象的情況下,沒有人會是GCed。
  • 的GC不遵循軟參考A(並且有它沒有硬引用)。 A是GCed,B是GCed,如果沒有活對象有引用。
+0

+1,感謝您的解釋。 – Jeffrey

+0

非常感謝。 – performanceuser

+1

順便說一句,只有真正的GC根的JNI引用對象的其餘部分(應該是)資格GC(這就是爲什麼類加載器有一個'矢量 classes') – bestsss