Object.finalize()
,我想我理解其中的原因,但我很难看到如何替换它。
我有一个名为Configuration的实用程序类,它实际上有一个实例,该实例拥有应用程序中的所有内容并持续应用程序的持续时间。它提供的服务之一是日志记录:在第一次请求记录消息时,创建记录器(由于各种遗留原因,它是我自己的记录器而不是标准记录器),并且在字段中保存了引用。配置对象,以及在应用程序终止时,无论是正常还是异常,我想释放记录器所拥有的任何资源(这是一个黑盒子,因为我的库的用户可以提供他们自己的实现)。
目前,这是通过调用Configuration.finalize()
的{{1}}方法实现的。
我应该做什么呢?
答案 0 :(得分:6)
Phantom references是finalize()
的一般替代品。 Java运行时的许多类已经在使用它们。
使用Phantom references有点费力,你必须维护自己的引用列表和事后处理线程。另一方面,你完全掌控。
幻影参考设置的 This article解释并比较了Java finalize()
和Phantom references的实现。
答案 1 :(得分:6)
Java 9引入了Cleaner和Cleanable实用程序类,它们负责将虚拟引用连接到队列和清理该队列的清理线程。
虽然这可以让你在拥有对象死亡后分离出将要进行事后清理的证人,但所有关于GC触发的资源管理的警告仍然适用,即仍然可以依赖{{1}和try-with-resources块来管理资源的生命周期,而不是垃圾收集器。
答案 2 :(得分:3)
您可以将线程shutdown hook添加到运行时:
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
// cleanup code
}));
当VM终止时调用此函数,因此在您的特定情况下它应该是finalize
的良好替代
答案 3 :(得分:2)
恕我直言,你的应用程序不负责告诉记录器清理它自己的烂摊子。记录器本身可以和 这样做(与IO流或数据库连接不同),它应该活得很长。
但您已提供logger.close()
...好的,我建议如下:
close
是幂等的,即第二次关闭记录器是无操作。Runtime#addShutdownHook
和PhantomReference
,让他们都调用logger.close()
,以便在JVM终止或您的应用程序获得GC时调用它。< / LI>