gpt4 book ai didi

java - 为什么当你有 finalize() 时关闭资源很重要

转载 作者:行者123 更新时间:2023-11-29 04:25:32 28 4
gpt4 key购买 nike

好的,所以我知道您应该始终关闭您的流和其他 native 资源,但我目前不确定原因。

我明白其中一个原因,那就是可用资源数量有限,您希望在用完后立即释放它们。但是让我们假设您的应用程序不使用那么多资源,那么应该不需要关闭资源吧?

特别是因为您有 finalize() block ,它应该在 GC 到达时关闭所有 native 资源。

最佳答案

假设“你有 finalize() block ,当 GC 到达它时应该关闭所有 native 资源”首先是错误的。无法保证表示 native 资源的每个对象都具有这样的 finalize() 方法。

其次,资源不一定是native资源。
当你有,例如BufferedOutputStreamObjectOutputStreamZipOutputStream 包装 FileOutputStream,后者可能有一个 finalize () 方法释放底层 native 资源(依赖于实现),但不会写入正确写入数据所需的包装流的任何待处理数据。关闭包装器流是强制性的,以确保写入的输出是完整的。

天真地向这些包装流类添加一个 finalize() 方法来关闭它们是行不通的。当流对象被收集时,这意味着没有对它的引用,换句话说,不再有定向的应用程序→包装流→ native 流图。由于对象图可能是循环的,因此无法保证在死对象之间进行昂贵的顺序搜索会成功,这就是 JVM 甚至不尝试的原因。

或者,作为 the specification说:

The Java programming language imposes no ordering on finalize method calls. Finalizers may be called in any order, or even concurrently.

因此,包装器的 finalize() 方法不能保证在底层原生流的 finalize() 方法之前被调用,因此,底层原生流流可能在包装流之前已经完成并关闭,因此无法写入挂起的数据。

兔子洞变得更深了。对象实例由 JVM 根据代码需要维护,但代码可以优化为直接使用封装数据。如果包装流类具有 finalize() 方法,您可能会发现包装实例甚至可以比预期更早被释放,如 finalize() called on strongly reachable object in Java 8 中所述。 .

或者,简而言之,显式关闭是确保它在正确的时间点准确发生的唯一方法。

关于java - 为什么当你有 finalize() 时关闭资源很重要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46558100/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com