Java面试问题:finalize()方法

Java面试问题:finalize()方法,java,garbage-collection,finalize,Java,Garbage Collection,Finalize,在一次采访中,我被赋予了以下短语: 调用对象的 finalize()方法是最后一件事 这发生在对象被激活之前 垃圾收集 我的回答是: 真的 假的 我选择了True,但它错了。 你能解释一下原因吗?不能保证总是调用finalize(),甚至垃圾收集也会运行 假设您的程序结束(通过调用System.exit()或当所有正在运行的线程结束时),那么JVM将退出,它不会清理所有内容并对所有对象调用finalize() 因此,将绝对必须运行的清理任务放在finalize()方法中不是一个好主意。我认为

在一次采访中,我被赋予了以下短语:

调用对象的 finalize()方法是最后一件事 这发生在对象被激活之前 垃圾收集

我的回答是:

  • 真的
  • 假的
我选择了
True
,但它错了。
你能解释一下原因吗?

不能保证总是调用
finalize()
,甚至垃圾收集也会运行

假设您的程序结束(通过调用
System.exit()
或当所有正在运行的线程结束时),那么JVM将退出,它不会清理所有内容并对所有对象调用
finalize()


因此,将绝对必须运行的清理任务放在
finalize()
方法中不是一个好主意。

我认为这暗示了一个事实,即在GC真正丢弃对象之前,实际上还有其他事情可以做/发生在对象上

引用参考文献:

[…]最终确定方法可能需要任何 操作,包括创建此对象 对其他线程再次可用;最终确定的通常目的, 但是,是执行清理操作 在对象被不可撤销地丢弃之前。例如,最终确定 表示 可能存在输入/输出连接 执行显式I/O事务以 在断开连接之前断开连接 对象是永久的 丢弃。[…]


因此,从这个角度来看,在GC丢弃它之前,终结过程并不是最后一件事。

顺序不同:

  • 首先收集对象
  • 然后对象已完成
  • 对象生命周期:

  • 创造
  • 正在使用(强可达)
  • 无形的
  • 遥不可及
  • 收集
  • 定稿
  • 解除分配

  • 我想你可以为这两个答案辩护,
    finalize()
    在垃圾收集器收集对象之前被它调用,但你不能确定在应用程序结束之前会发生这种情况。并非所有可称为垃圾收集的对象都必须被收集。任何对象都不能依赖于调用
    finalize()
    方法。

    如前所示,顺序是错误的

    当gc识别出对象不可访问时,对象将其状态更改为collected

    那么,在检测到这种“无法访问”的情况之前,谁应该采取行动来完成对象呢?事实上,垃圾收集器将收集的对象标记为终结(如果对象终结方法被重写)。我们真的不想最终确定仍然可以访问的对象,例如“正在使用”


    无论如何,这个问题很好,因为您倾向于说“是的,这是真的”。

    您可以通过指向finalize方法中的对象来复活该对象,这样在调用finalize方法后,GC可能不会收集该对象。但当对象再次可用于垃圾收集时,它不会调用该对象的finalized方法,因为它已标记/标记为finalized。因此,在GC之前,可能需要调用finalize方法,或者对象可以复活

    请阅读这篇文章:@Vash,那篇文章已经过时了这并没有回答这个问题它部分地回答了这个问题,并提供了一些有用的信息,说明为什么
    finalize()
    没有许多程序员认为的那么有用。四处散布有用的琐事可能会很好,但是坚持这个话题更好。谢谢你的回答。虽然这不是一个确切的答案,但这是一个令人愉快的琐事。已收集不是对象生命周期的最终状态,而是已解除分配+对于今天的链接和学习:)非常感谢。非常有用的知识。问题是“收集”是一个口语术语,它的解释不同。有些人说“已收集”是指垃圾收集器确定某个对象不可访问的事件,其他人则用同一个词表示对象的内存已被回收。根据这种主观意义,答案是不同的。在规范中,没有“收集”状态。