了解 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中文网其他相关文章!