【问题标题】:Does Garbage Collector ignores Exception垃圾收集器是否忽略异常
【发布时间】:2014-05-03 04:44:29
【问题描述】:

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

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

【问题讨论】:

  • finalize 方法传播的异常将被忽略。本质上,finalize 方法是运行的,无论它是“正常”结束还是异常结束,对象都被标记为不再尝试结束。在下一个 GC 循环中,如果不再引用该对象,则将忽略终结器并收集该对象。 (终结器可以再次引用它。)

标签: java garbage-collection finalize


【解决方案1】:

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

【讨论】:

  • 也是垃圾收集器忽略Exception并且该对象的终结终止的情况,这是否意味着该对象始终保留在内存中?
  • @Vishrant 终结器线程不会告诉 GC 任何事情,因此不会让 Exception 搞砸。
  • @Vishrant GC 独立于终结器线程工作。当 GC 运行时,它只收集不可强到达且不需要调用 finalize() 的对象。终结器线程只是通过丢弃它们并假装它们没有发生来忽略异常/错误。
【解决方案2】:

来自Effective Java

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

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

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-05-25
      • 2012-04-21
      • 1970-01-01
      • 2023-03-07
      • 2011-01-18
      • 1970-01-01
      • 2016-02-29
      • 1970-01-01
      • 2018-12-30
      相关资源
      最近更新 更多