首页 >Java >java教程 >为什么 Java 8 中的 Finalize() 调用会意外触发流关闭?

为什么 Java 8 中的 Finalize() 调用会意外触发流关闭?

Susan Sarandon
Susan Sarandon原创
2024-12-14 09:46:25383浏览

Why Are finalize() Calls Unexpectedly Triggering Stream Closures in Java 8?

了解 Java 8 中的 Finalize() 调用

从 Java 7 到 Java 8 的过渡中,消息处理应用程序偶尔会遇到异常与流关闭相关。调查显示,对持有流的对象意外调用了 Finalize(),导致其在主动读取操作期间关闭。

最初令人费解的是,此行为可归因于对垃圾收集的一个不太了解的方面。即使引用堆栈上存在的对象并且在活动方法调用期间,对象仍然可以被视为不可访问。当没有后续代码访问其引用时,就会发生这种情况,使其“死亡”。

如简化示例所示,即使在活动方法执行期间,对象也可以被最终确定并进行垃圾收集:

class FinalizeThis {
    @Override
    protected void finalize() {
        System.out.println("finalized!");
    }

    void loop() {
        for (int i = 0; i < 1,000,000,000; i++) {
            // Triggering GC with System.gc() doesn't guarantee garbage collection
        }
    }

    public static void main(String[] args) {
        new FinalizeThis().loop();
    }
}

在此示例中,FinalizeThis 对象的引用保留在范围内,但由于缺乏与其进一步交互而无法访问。因此,它有资格进行最终确定和随后的垃圾回收。

在报告的情况下,MIMEBodyPart 对象可能已存储在带有 m_ 前缀的局部变量中,满足潜在无法访问的条件。通过按照注释中的建议修改对象的存储位置,终结行为停止。

值得注意的是,可以通过引入编译指令来规避此终结问题。 -Xcomp 标志强制方法在执行前进行编译,允许编译器执行可达性分析并避免不必要的终结调用。

以上是为什么 Java 8 中的 Finalize() 调用会意外触发流关闭?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn