2

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

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

4

2 回答 2

1

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

在实践中是的。

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

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

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


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

那将是一种方法。

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

并且可能还有其他计划。

如果您真的非常想知道它是如何完成的,垃圾收集器源是免费提供的。

于 2013-10-09T15:00:06.433 回答
1

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

于 2013-10-09T19:00:21.260 回答