2013-10-09 52 views
2

Java的finalize方法在JVM確定對象符合垃圾回收條件後調用。對於何時會發生這種情況,或者在程序退出之前是否會發生這種情況,並沒有真正的保證。我的問題是finalize是否爲保證被調用的對象實際上是垃圾收集。我特別想到代代GC中最年輕一代的物體。終結者如何與代GC進行交互?

在世代GC中,最年輕的一代通常會使用簡單的標記清除收集進行GC'd處理,其中只有活動對象被遍歷並複製到新空間。因此,最年輕一代的垃圾實際上並沒有穿過。如果垃圾未遍歷,那麼我們如何保證finalize被稱爲垃圾對象?看來,a)不能保證finalize將被調用這些對象在最年輕一代變成垃圾,或者b)保證finalize將被調用,但覆蓋finalize的對象以某種方式處理不同。

+0

看到這個答案:http://stackoverflow.com/questions/7880569/does-jvm-gc-call-finalize-on-程序線程退出 – wheaties

回答

1

我的問題是finalize是否保證被調用的對象實際上是垃圾收集。

在實踐中是的。

實際保證是finalize方法將在對象最終回收之前調用。

如果垃圾沒有遍歷,那麼我們如何保證finalize被調用的對象變成垃圾?

在遍歷(標記)期間不調用finalize方法。它被稍後調用的對象沒有在標記階段被標記。標記階段標記的任何對象都是可到達的,而不是回收的候選對象。


的問題是,如何在JVM知道哪些對象沒有得到標記?這似乎需要遍歷苗圃中的所有對象,即使是那些垃圾。

這將是一種做法。

另一種方法是創建一個特殊的(非GC根)對象列表「可終結」列表。活體物體撤離後,遍歷列表以檢查所有可終結對象的舊空間副本。任何沒有撤離的人都需要敲定。

也可能有其他方案。

如果你確實想知道它是如何完成的,垃圾收集器的源代碼是免費的。

+0

問題是,JVM如何知道哪些對象沒有被標記?這似乎需要遍歷苗圃中的所有對象,即使是那些垃圾。 – pchiusano

+0

不,它只需要遍歷「finalizable」對象的特殊「列表」來查看它們是否被標記。 –

+0

@BjörnAntonsson - 我想我只是這麼說的。往上看 :-) –