如何检测何时不再引用对象

时间:2008-10-16 13:29:59

标签: java reference weak-references

有没有办法创建一个寄存器,在最后一次释放某个对象的时候会被调用?

一个示例是由物理数据文件支持的对象,一旦对象变为未引用,该文件应该被关闭而不是重命名。如果没有在该对象上显式调用“关闭”方法,那将是可能的。

我从Weak / Phantom参考区域了解的所有通知机制仅表明通知将在某个时间点发生,但没有保证何时会发生...

7 个答案:

答案 0 :(得分:13)

简而言之,不。

Java规范明确拒绝您知道何时释放最后一个引用。 JVM实现(和优化)依赖于此。没有钩子。

答案 1 :(得分:4)

根据我的理解,我已经找了一些时间为java对象找到“析构函数”,没有办法知道你什么时候丢失了最后一个引用。 Java跟踪对象的引用,但出于性能原因,仅在垃圾回收期间更新此信息。

最接近的是在垃圾收集过程中应该调用的finalize方法,但是不能保证它会被调用。

答案 2 :(得分:4)

我认为WeakReference会做你想要的。只要弱可达(即所有强引用都消失),WeakReference就会被放入ReferenceQueue中。

Ethan Nicholas查看此文章。

如果您担心某些引用在关闭时未到达ReferenceQueue,则保留所有对象的列表(使用WeakReferences或PhantomReferences)。添加一个关闭钩子,检查列表中是否有任何未完成的引用,并执行您需要的任何操作。

答案 3 :(得分:2)

问题是,“你如何实现这一点,没有东西持有对象的引用?”

即使您可以通过我们将调用HandleManager的服务来解决问题,HandleManager也必须创建对该对象的新引用,以传递给您的处理程序。然后,你的处理程序可以(a)存储对它的引用,这会混淆期望破坏未引用对象的HandleManager;或者(b)发布参考文献,这意味着最终的参考文献再次被释放,这意味着必须再次调用处理程序....

答案 4 :(得分:2)

如果您需要管理文件等外部资源,那么您在java中可以做的最好的就是close()函数(无论您选择什么名称)。您可以使用finalize()作为“腰带和吊带”保险单,但这具有不可预测的时间。所以你的主要防线需要是close()函数。

请参阅我的回答Why would you ever implement finalize()?

答案 5 :(得分:0)

这不能用Java完成 - 据我所知,它需要一个引用计数垃圾收集器。您是否考虑过根据需要打开和关闭对象的物理数据文件,而不是在对象的生命周期内保持打开状态?

答案 6 :(得分:-1)

可以覆盖您对象中的finalize(),但由于其他人提到的原因,这是有问题的。

对于您的具体示例,您可以查看使用File.deleteOnExit()之类的内容,这会在VM退出后删除该文件。