4

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

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

4

3 回答 3

2

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

于 2014-03-25T11:32:00.977 回答
2

有效的Java

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

问题是当在finalize方法内部引发未捕获的异常时,对象可能会处于损坏状态。方法中忽略了未捕获的异常finalize,但这并不意味着 GCException会像您的问题所暗示的那样忽略。

于 2014-03-25T11:32:48.777 回答
2

GC 本身不会调用 finalize。相反,当 GC 找到不存在强根引用的“可终结”对象时,它会将其标记为“不可终结”并将其移动到需要立即终结的对象队列中,并在必要时启动一个线程来处理队列中的每个项目。队列本身将充当对未运行 finalize 方法的对象的强根引用,并且当前正在运行的终结器的执行上下文将使其保持活动状态,但是一旦控制离开终结器,该对象将有资格被收集除非对它的强根引用已存储在其他地方。

终结器实际上不需要做任何事情来使 GC 收集对象。当对象被移动到需要立即终结的对象队列时,GC 本身会清除“finalizable”标志,并且将对象从队列中拉出以运行它的行为会将队列作为根引用消除。到终结器执行时,它的执行上下文将是唯一使对象保持活动状态的东西,因此通过任何方式(异常或其他方式)离开该执行上下文将使对象有资格进行垃圾回收。

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

于 2014-03-26T21:40:29.830 回答