JDK-8274609 JEP 421: Deprecate Finalization for Removal

Posted 笑虾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK-8274609 JEP 421: Deprecate Finalization for Removal相关的知识,希望对你有一定的参考价值。

JDK9 中已标记为不推荐。然后是可以手动关闭,再后是默认关闭,最后移除

@Deprecated(since="9")
protected void finalize​() throws Throwable

官方的示例有说明,必须手动调用基类的finalize。并指出这是个坑,很容易遗漏。

@Override
protected void finalize() throws Throwable 
    try 
        ... // cleanup subclass state
     finally 
        super.finalize();
    

这套终止化机制本身存在问题。finalize 可能会导致性能问题、死锁和挂起。finalize 内出错时可能导致资源泄漏; 如果不再需要,也没有办法取消; 在不同的对象中调用 finalize 也没法指定顺序。 此外,对于最终完成终止化的时间也没有保障。只有在无尽的等待之后,最终有可能在终结对象上调用 finalize。当类的实例持有非堆资源,它应该提供一个方法来显式释放这些资源,如果合适的话,它们还应该实现 AutoCloseable。 当对象变得不可访问时,CleanerPhantomReference 提供了更灵活和有效的方法来释放资源。

当垃圾收集确定对象不再被引用时,由垃圾收集器对对象调用 finalize。子类重写 finalize 方法以释放系统资源或执行其他清理。

finalize 的通常约定是,如果当Java™虚拟机确定不会再有任何活着的线程的对象可以通过任何方式访问该对象时,调用finalize。除非是某个也即将结束的其他对象或类所采取的访问操作。 finalize 方法可以执行任何操作,包括使该对象对其他线程再次可用; 然而,finalize 的通常目的是在对象被不可撤销地丢弃之前执行清理操作。 例如,表示输入/输出连接的对象的 finalize 方法可能会执行显式的I/O事务,在对象被永久丢弃之前断开连接。

Object 类的 finalize 方法不执行任何特定操作; 它就是直接返回。 留给 Object 的子类来重写这个定义。

protected void finalize() throws Throwable  

Java编程语言不保证哪个线程将调用任何给定对象的 finalize 方法。 但是,可以保证调用 finalize 的线程在调用 finalize时不会持有任何用户可见的同步锁。 如果 finalize 方法抛出未捕获的异常,则忽略该异常并终止该对象的终结。

在调用对象的 finalize 方法之后,直到Java虚拟机再次确认没有任何活着的线程和其他对象能通过任何方法访问到该对象,此时对象才可能会被丢弃,否则不会采取进一步的操作。

对于任何给定的对象,Java虚拟机最多只会调用一次 finalize 方法。

finalize 方法抛出的任何异常都会导致放弃此对象的终结,否则会被忽略。 (后半句我没看懂,“否则”是个什么场景)

参考资料

JEP 421: Deprecate Finalization for Removal

以上是关于JDK-8274609 JEP 421: Deprecate Finalization for Removal的主要内容,如果未能解决你的问题,请参考以下文章

去重 oracle

JEP解读与尝鲜系列4 - Java 16 中对于 Project Valhalla 的铺垫

如何在 jep 中使用其他 python 模块?

JEP解读与尝鲜系列4 - Java 16 中对于 Project Valhalla 的铺垫

JEP 305: InstanceOf

JDK 11有望实现JEP 321: HTTP Client (Standard) 特性