在JVM确定对象符合垃圾回收条件后,将调用Java的finalize
方法。关于这种情况何时会发生,或者在程序退出之前是否会发生,都没有真正的保证。我的问题是finalize
是否保证为实际上被垃圾收集的对象调用。我特别想到最年代的一代GC中的物体。
在世代GC中,最年轻的一代通常使用简单的标记扫描集合进行GC,其中只有活动对象被遍历并复制到新空间。因此,实际上并没有遍历最年轻一代的垃圾。如果没有遍历垃圾,那么我们如何保证为变成垃圾的对象调用finalize
?似乎要么a)不能保证将finalize
调用这些在最年轻的一代中成为垃圾的对象,或者b)保证将finalize
被调用,但是对象是覆盖finalize
以某种方式处理不同。
答案 0 :(得分:1)
我的问题是,对于实际上是垃圾收集的对象,是否保证调用finalize。
在实践中是的。
实际的保证是在最终回收对象之前调用finalize方法。
如果没有遍历垃圾,那么我们如何保证为变成垃圾的对象调用finalize?
在遍历(标记)期间不调用finalize方法。稍后在未在标记阶段标记的对象上调用它。在标记阶段标记的任何对象都是可到达的......而不是回收的候选对象。
问题是,JVM如何知道哪些对象没有被标记?这似乎需要遍历托儿所中的所有对象,甚至是那些垃圾。
这将是一种做法。
另一种方法是拥有一个特殊的(非GC根)列表的“可终结的”对象列表。在活动对象被撤离后,遍历列表以检查所有可终结对象的旧空间副本。其中任何尚未撤离的人都需要最终确定。
也可能有其他方案。
如果您确实想知道它是如何完成的,那么垃圾收集器源是免费提供的。
答案 1 :(得分:1)
这篇文章向您展示了可终结对象的一个实现如何工作http://www.fasterj.com/articles/finalizer1.shtml