终结者如何与世代GC相互作用?

时间:2013-10-09 14:49:20

标签: java garbage-collection jvm

在JVM确定对象符合垃圾回收条件后,将调用Java的finalize方法。关于这种情况何时会发生,或者在程序退出之前是否会发生,都没有真正的保证。我的问题是finalize是否保证为实际上被垃圾收集的对象调用。我特别想到最年代的一代GC中的物体。

在世代GC中,最年轻的一代通常使用简单的标记扫描集合进行GC,其中只有活动对象被遍历并复制到新空间。因此,实际上并没有遍历最年轻一代的垃圾。如果没有遍历垃圾,那么我们如何保证为变成垃圾的对象调用finalize?似乎要么a)不能保证将finalize调用这些在最年轻的一代中成为垃圾的对象,或者b)保证将finalize被调用,但是对象是覆盖finalize以某种方式处理不同。

2 个答案:

答案 0 :(得分:1)

  

我的问题是,对于实际上是垃圾收集的对象,是否保证调用finalize。

在实践中是的。

实际的保证是在最终回收对象之前调用finalize方法。

  

如果没有遍历垃圾,那么我们如何保证为变成垃圾的对象调用finalize?

在遍历(标记)期间不调用finalize方法。稍后在未在标记阶段标记的对象上调用它。在标记阶段标记的任何对象都是可到达的......而不是回收的候选对象。


  

问题是,JVM如何知道哪些对象没有被标记?这似乎需要遍历托儿所中的所有对象,甚至是那些垃圾。

这将是一种做法。

另一种方法是拥有一个特殊的(非GC根)列表的“可终结的”对象列表。在活动对象被撤离后,遍历列表以检查所有可终结对象的旧空间副本。其中任何尚未撤离的人都需要最终确定。

也可能有其他方案。

如果您确实想知道它是如何完成的,那么垃圾收集器源是免费提供的。

答案 1 :(得分:1)

这篇文章向您展示了可终结对象的一个​​实现如何工作http://www.fasterj.com/articles/finalizer1.shtml