2013-07-06 89 views
9

假設有一個類A的對象a,它持有對B類的另一個對象b的引用。這是對b的唯一引用。所以現在,如果所有對a的引用都被刪除,那麼a就準備好了GC。這是否意味着b也準備好收集垃圾?因爲儘管b有一個引用(在a中),但是它是無法訪問的,因爲a是無法訪問的。如果僅從垃圾中引用對象垃圾,那麼它是垃圾嗎?

那麼這種情況到底如何?我的意思是垃圾收集的順序。

+0

可能重複http://stackoverflow.com/questions/1910194/garbage-collection-in-java-and -irir-references) – delnan

+1

它更好地考慮垃圾收集器,弄清楚什麼**不適用於垃圾收集和收集剩餘部分。如果從根目錄可以看出它不適用 –

回答

13

一旦從根目錄無法訪問對象,它就會被收集。請參閱this question瞭解GC根的解釋。

假設子圖內沒有任何節點可以到達,則會收集整個子圖(如您所描述的那樣)。

Java(和.NET)使用mark和sweep垃圾回收處理這類問題。

引用計數系統(如C++的std::shared_ptr<T>)在循環依賴不可達的情況下可能會失敗。這對於Java/.NET GC來說不是問題。

+0

+1我在這裏沒有看到任何反對票的理由。 –

+3

如果有一個downvoter誰無故downvotes,然後還有其他人喜歡我,誰給予好評了一個很好的答案:) –

1

Java GC足夠聰明,可以收集孤立對象的島嶼,儘管它們可能指向對方。因此,b也有資格進行垃圾回收。這裏要注意的是,雖然你有一個參考b這不是生活從意義上說,它不能從您的程序的根目錄。

+1

這好,否則循環引用(A有B和B到A的引用)永遠不可能收集,但也可能無法訪問 –

+0

爲什麼投票? –

+0

似乎像somesones投了很多這個問題的好答案。有些人就是這樣 –

0

這取決於GC。 JVM可以被告知使用不同的GC,並且通常使用3個GC作爲一個(eden,copy,markcompact)。

在任何典型的GC 在引用計數的情況你描述的處理乾淨,既OBJ文件被收集。想想它有兩個階段:首先「a」被注意到並收集,然後「b」被注意到並收集。再次提醒:具體的注意方式取決於GC。

+0

如果你有循環引用,那麼我的經驗是,refcounting失敗。也就是說,如果A-> B和B-> A,都有一個計數,但都不可達。 –

+2

在OP描述的內容中沒有從「b」到「a」的引用。 –

+0

的確如此,但如果我沒有弄錯,那麼在編輯之前,您的回答並未重點強調。無論如何,GC是一個很大的話題,OP顯然是新手,我們可能會從介紹性方面脫節:) –

-1

這正是GC的要點。由於b從主線程不可訪問,所以將被垃圾收集。重要的不僅僅是數量。