Java面试题:finalize()方法
Posted
技术标签:
【中文标题】Java面试题:finalize()方法【英文标题】:Java Interview Question: finalize() method 【发布时间】:2011-03-19 10:11:51 【问题描述】:我在一次采访中得到了以下短语:
对象的调用 finalize() 方法是最后一件事 发生在一个对象之前 垃圾收集。
我必须通过以下方式回答:
是的 错误我选择了True
,但这是错误的。
你能解释一下为什么吗?
【问题讨论】:
请阅读这篇文章:codeguru.com/java/tij/tij0051.shtml @Vash,那篇文章已经过时了 【参考方案1】:无法保证finalize()
将始终被调用,甚至根本不会运行垃圾回收。
假设您的程序结束(通过调用System.exit()
或当所有正在运行的线程结束时),那么JVM 将退出,它不会清理所有内容并在所有对象上调用finalize()
。
因此,将绝对必须运行的清理任务放在finalize()
方法中并不是一个好主意。
【讨论】:
这没有回答问题 它部分回答了这个问题,并提供了一些有用的信息,说明为什么finalize()
不像许多程序员想象的那么有用。
散布有用的琐事可能会很好,但坚持主题会更好。
感谢您的回答。尽管不是一个确切的答案,但很高兴知道琐事。【参考方案2】:
我认为这暗示了在 GC 真正丢弃它之前,实际上还有其他事情可以完成/发生在对象上。
引用参考文献:
[...]finalize 方法可以采用任何 动作,包括制作这个对象 可再次用于其他线程;完成的通常目的, 但是,是执行清理操作 在对象被不可撤销地丢弃之前。例如,最终确定 表示对象的方法 输入/输出连接可能 执行显式 I/O 事务以 在之前断开连接 对象是永久的 丢弃。[...]
因此,从这个角度来看,最终确定过程并不是 GC 丢弃它之前的最后一件事。
【讨论】:
【参考方案3】:顺序不同:
-
首先对象被收集。
然后对象最终确定。
见http://java.dzone.com/articles/ocajp-7-object-lifecycle-java
对象生命周期:
已创建 使用中(强可达) 不可见 无法访问 已收集 敲定 已解除分配
【讨论】:
已确认。 collected 不是对象生命周期的最终状态,它是deallocated。为链接+1,今天学习一些东西:) 非常感谢。很有用的知识。 这个问题是“收集”是一个口语术语,解释不同。有些人说“已收集”是指垃圾收集器确定对象不可访问的事件,其他人使用相同的词表示对象的内存已被回收。根据这个主观意义,答案是不同的。在规范中,没有所谓的“收集”状态。【参考方案4】:我想你可以为这两个答案辩护,finalize()
在收集对象之前由垃圾收集器调用,但你不能确定在应用程序结束之前是否会出现这种情况。并非所有可以被认为是垃圾收集的对象都必须被收集。您可能永远不会依赖于为任何对象调用 finalize()
方法。
【讨论】:
【参考方案5】:顺序错误,正如DR 已经显示的那样。
当 gc 识别出该对象不可访问时,该对象将其状态更改为已收集。
那么谁应该在检测到这种“无法到达”的情况之前采取行动来完成一个对象?事实上,垃圾收集器将收集到的对象标记为终结(如果对象终结方法被覆盖)。而且我们真的不想最终确定仍然可以访问的对象,例如'正在使用'。
无论如何,这是个好问题,因为您倾向于说“是的,这是真的”。
【讨论】:
【参考方案6】:您可以在 finalize 方法中通过指向某个对象来复活该对象,这样在调用 finalized 方法后该对象可能不会被 GC 收集。但是当该对象再次可用于垃圾收集时,它不会调用该对象的最终方法,因为它已被标记/标记为已完成。所以在 GC 之前可能会发生调用 finalize 方法或者对象可以复活。
【讨论】:
以上是关于Java面试题:finalize()方法的主要内容,如果未能解决你的问题,请参考以下文章