垃圾收集器是否忽略异常

时间:2014-03-25 11:15:49

标签: java garbage-collection finalize

我正在阅读Any Exception thrown by finalize method is ignored by GC thread and it will not be propagated further,但是忽略GC的异常是什么原因。

该对象的终结也终止,这是否意味着该对象始终保留在内存中?

3 个答案:

答案 0 :(得分:2)

它忽略了异常,因为它无法处理它。 finalize()方法的目的是在对象死亡之前进行最后的清理。如果要在finalize()方法中处理异常,则必须添加代码才能执行此操作。

答案 1 :(得分:2)

来自 Effective Java

  

如果您还不确定应该避免使用终结器,那么这是另一个值得考虑的因素:如果在最终确定期间抛出未捕获的异常,则忽略该异常,并终止该对象的终结[JLS,12.6]。未捕获的异常会使对象处于损坏状态。如果另一个线程试图使用这样一个损坏的对象,可能会导致任意非确定性行为。通常,未捕获的异常将终止线程并打印堆栈跟踪,但如果它出现在终结器中则不会 - 它甚至不会打印警告。

问题是当finalize方法中引发未捕获的异常时,对象可能会保持在损坏状态。 finalize方法会忽略未捕获的异常,但并不意味着GC会忽略Exception,如您的问题所示。

答案 2 :(得分:2)

GC本身不会调用finalize。相反,当GC找到"可终结的"没有强根源引用的对象,它标记为"不可终结的"并将其移动到需要立即完成的对象队列中,并在必要时启动一个线程,该线程将处理队列中的每个项目。队列本身将作为对其最终化方法尚未运行的对象的强大根本引用,并且当前运行的终结器的执行上下文将使其保持活动状态,但是一旦控制离开终结器,该对象将符合条件收集除非对其有强烈根源的引用存储在别处。

终结器实际上不需要做任何事情来使GC能够收集对象。 GC本身可以清除"可终结的"当对象移动到需要立即完成的对象队列时标记,并且将对象拉出队列以便运行它的行为将队列作为有根引用消除。当终结器执行时,其执行上下文将是保持对象存活的唯一因素,因此通过任何方式(例外或其他方式)保留该执行上下文将使该对象有资格进行垃圾收集。

请注意,finalize方法的真正目的不是让对象自己做事,而是允许对象通知代表他们行动的外部实体不再需要他们的服务。如果终结者在没有发送此类通知的情况下死亡,则不会发送通知。