用Java替换finalize()

Mic*_*Kay 10 garbage-collection finalizer java-9

Object.finalize() 在Java 9中已弃用,我想我理解其中的原因,但我很难看到如何替换它.

我有一个名为Configuration的实用程序类,它实际上有一个实例,它拥有应用程序中的所有内容,并持续应用程序的持续时间.它提供的服务之一是记录:在第一次请求记录消息时,创建记录器(由于各种遗留原因,它是我自己的记录器而不是标准记录器),并在Configuration对象的字段中保存引用,并且在应用程序终止时,无论是正常还是异常,我想释放记录器所拥有的任何资源(这是一个黑盒子,因为我的库的用户可以提供他们自己的实现).

目前,这是通过Configuration.finalize()调用方法实现的logger.close().

我应该做什么呢?

Ale*_*zin 6

幻影参考是一般的替代品finalize().Java运行时的许多类已经在使用它们.

使用Phantom引用有点费力,你必须维护自己的引用列表和事后处理线程.另一方面,你完全掌控着.

以下是 Phantom参考设置的一个简单示例.

本文解释并比较了Java finalize()Phantom引用的实现.


the*_*472 6

Java 9引入了Cleaner和Cleanable实用程序类,它们负责连接对队列的幻像引用和排空该队列的清理线程.

虽然这可以让你在拥有对象死亡后分离出将要执行事后清理的见证,但是关于GC触发的资源管理的所有警告仍然适用,即仍然优先依赖AutoClosable并尝试使用资源块管理资源的生命周期,而不是垃圾收集器.

  • 体面的例子 http://www.enyo.de/fw/notes/java-finalization-revisited.html (2认同)

Lot*_*har 5

您可以将线程作为关闭挂钩添加到运行时:

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    // cleanup code
}));
Run Code Online (Sandbox Code Playgroud)

这在 VM 终止时被调用,因此finalize在您的特定情况下它应该是一个很好的替代品