【发布时间】:2011-03-19 10:11:51
【问题描述】:
我在一次采访中得到了以下短语:
对象的调用 finalize() 方法是最后一件事 发生在一个对象之前 垃圾收集。
我必须通过以下方式回答:
- 是的
- 错误
我选择了True,但这是错误的。
你能解释一下为什么吗?
【问题讨论】:
-
@Vash,那篇文章已经过时了
标签: java garbage-collection finalize
我在一次采访中得到了以下短语:
对象的调用 finalize() 方法是最后一件事 发生在一个对象之前 垃圾收集。
我必须通过以下方式回答:
我选择了True,但这是错误的。
你能解释一下为什么吗?
【问题讨论】:
标签: java garbage-collection finalize
无法保证finalize() 将始终被调用,甚至根本不会运行垃圾回收。
假设您的程序结束(通过调用System.exit() 或当所有正在运行的线程结束时),那么JVM 将退出,它不会清理所有内容并在所有对象上调用finalize()。
因此,将绝对必须运行的清理任务放在finalize() 方法中并不是一个好主意。
【讨论】:
finalize() 不像许多程序员想象的那么有用。
我认为这暗示了在 GC 真正丢弃它之前,实际上还有其他事情可以完成/发生在对象上。
引用参考文献:
[...]finalize 方法可以采用任何 动作,包括制作这个对象 可再次用于其他线程;完成的通常目的, 但是,是执行清理操作 在对象被不可撤销地丢弃之前。例如,最终确定 表示对象的方法 输入/输出连接可能 执行显式 I/O 事务以 在之前断开连接 对象是永久的 丢弃。[...]
因此,从这个角度来看,最终确定过程并不是 GC 丢弃它之前的最后一件事。
【讨论】:
顺序不同:
见http://java.dzone.com/articles/ocajp-7-object-lifecycle-java
对象生命周期:
- 已创建
- 使用中(强可达)
- 不可见
- 无法访问
- 已收集
- 敲定
- 已解除分配
【讨论】:
我想你可以为这两个答案辩护,finalize() 在收集对象之前由垃圾收集器调用,但你不能确定在应用程序结束之前是否会出现这种情况。并非所有可以被认为是垃圾收集的对象都必须被收集。您可能永远不会依赖于为任何对象调用 finalize() 方法。
【讨论】:
顺序错误,正如DR 已经显示的那样。
当 gc 识别出该对象不可访问时,该对象将其状态更改为已收集。
那么谁应该在检测到这种“无法到达”的情况之前采取行动来完成一个对象?事实上,垃圾收集器将收集到的对象标记为终结(如果对象终结方法被覆盖)。而且我们真的不想最终确定仍然可以访问的对象,例如'正在使用'。
无论如何,这是个好问题,因为您倾向于说“是的,这是真的”。
【讨论】:
您可以在 finalize 方法中通过指向某个对象来复活该对象,这样在调用 finalized 方法后该对象可能不会被 GC 收集。但是当该对象再次可用于垃圾收集时,它不会调用该对象的最终方法,因为它已被标记/标记为已完成。所以在 GC 之前可能会发生调用 finalize 方法或者对象可以复活。
【讨论】: