我正在阅读,Any Exception thrown by finalize method is ignored by GC thread and it will not be propagated further
但是 GC 忽略异常的原因是什么。
该对象的最终确定也会终止,这是否意味着该对象始终保留在内存中?
我正在阅读,Any Exception thrown by finalize method is ignored by GC thread and it will not be propagated further
但是 GC 忽略异常的原因是什么。
该对象的最终确定也会终止,这是否意味着该对象始终保留在内存中?
它忽略异常,因为它无法处理它。finalize() 方法的目的是在对象死亡之前进行最后的清理。如果要在 finalize() 方法中处理异常,则必须添加代码来执行此操作。
从有效的Java
如果您还不确定应该避免使用终结器,这里还有一个值得考虑的花絮:如果在终结期间抛出未捕获的异常,则忽略该异常,并且该对象的终结终止 [JLS,12.6]。未捕获的异常会使对象处于损坏状态。如果另一个线程试图使用这样一个损坏的对象,则可能会导致任意的不确定行为。通常,未捕获的异常将终止线程并打印堆栈跟踪,但如果它发生在终结器中则不会——它甚至不会打印警告。
问题是当在finalize
方法内部引发未捕获的异常时,对象可能会处于损坏状态。方法中忽略了未捕获的异常finalize
,但这并不意味着 GCException
会像您的问题所暗示的那样忽略。
GC 本身不会调用 finalize。相反,当 GC 找到不存在强根引用的“可终结”对象时,它会将其标记为“不可终结”并将其移动到需要立即终结的对象队列中,并在必要时启动一个线程来处理队列中的每个项目。队列本身将充当对未运行 finalize 方法的对象的强根引用,并且当前正在运行的终结器的执行上下文将使其保持活动状态,但是一旦控制离开终结器,该对象将有资格被收集除非对它的强根引用已存储在其他地方。
终结器实际上不需要做任何事情来使 GC 收集对象。当对象被移动到需要立即终结的对象队列时,GC 本身会清除“finalizable”标志,并且将对象从队列中拉出以运行它的行为会将队列作为根引用消除。到终结器执行时,它的执行上下文将是唯一使对象保持活动状态的东西,因此通过任何方式(异常或其他方式)离开该执行上下文将使对象有资格进行垃圾回收。
请注意,finalize 方法的真正目的不是让对象自己做事,而是让对象通知代表他们行事的外部实体不再需要他们的服务。如果终结器在没有发送此类通知的情况下死亡,则不会发送通知。