我在接受采访时得到了以下短语:
调用Object的 finalize()方法是最后一件事 在对象之前发生的事情 被收集的。
我不得不回答:
我选择了True
,但这是错的。
你能解释一下为什么吗?
答案 0 :(得分:59)
订单不同:
请参阅http://java.dzone.com/articles/ocajp-7-object-lifecycle-java
对象生命周期:
- 创建
- 使用中(强烈可达)
- 隐形
- 无法到达
- 收集
- 已完成
- 释放
醇>
答案 1 :(得分:8)
我认为它提示事实上,在GC真正丢弃它之前,其他事情可以在对象上完成/发生。
引用参考文献:
[...] finalize方法可能需要任何方法 动作,包括制作这个对象 再次提供给其他线程;最终确定的通常目的, 但是,是执行清理操作 在对象被不可撤销地丢弃之前。例如,最终确定 表示对象的方法 输入/输出连接可能 执行显式I / O事务 打破之前的连接 对象是永久的 丢弃。强> [...]
所以从这个角度来看,最终确定过程并不是GC丢弃它之前的最后一件事。
答案 2 :(得分:2)
无法保证始终会调用finalize()
,甚至根本不会运行垃圾收集。
假设您的程序结束(通过调用System.exit()
或当所有正在运行的线程到达它们结束时),那么JVM将退出,它不会清除所有内容并在所有上调用finalize()
对象。
因此,放置绝对必须在finalize()
方法中运行的清理任务不是一个好主意。
答案 3 :(得分:2)
我想你可以为这两个答案辩护,在收集对象之前,垃圾收集器会调用finalize()
,但你无法确定在应用程序结束之前是否会出现这种情况。并非所有可被垃圾收集的对象都必须被收集。您可能永远不会依赖finalize()
方法来调用任何对象。
答案 4 :(得分:1)
订单错误,因为DR已经显示。
当gc识别出对象无法访问时,对象将其状态更改为收集。
那么谁应该在检测到这个'无法访问'的情况之前采取行动来完成一个对象?事实上,它是垃圾收集器,用于标记收集的对象以进行最终化(如果覆盖了对象的finalize方法)。我们真的不想最终确定仍然可以访问的对象,例如'正在使用'。
无论如何,这个问题很好,因为你倾向于说'是的,这是真的'。
答案 5 :(得分:0)
您可以通过使某些内容指向它来恢复finalize方法中的对象,这样在调用finalized方法后GC可能无法收集该对象。但是当对象再次可用于垃圾收集时,它不会调用该对象的最终方法,因为它已被标记/标记为已完成。所以在GC之前可能会发生调用finalize方法或对象可以复活。