gpt4 book ai didi

java - 为什么需要关闭 Java 中文件打开的连接?

转载 作者:行者123 更新时间:2023-12-01 17:45:41 25 4
gpt4 key购买 nike

我读到该文件是非托管资源,不会被垃圾收集器处理。

如果您不关闭文件,我确信如果没有任何内容引用该文件,对该文件的引用将被垃圾收集。那么究竟是什么保持开放呢?是操作系统级别的东西吗?就像 SQL 连接一样,我知道操作系统保持 TCP 端口打开,您最终可能会耗尽端口。但是对于文件来说,保持打开状态的是什么?

最佳答案

垃圾收集器最终可能会释放操作系统资源,这要归功于包装资源的类中的finalize()方法。然而,在未来的某个时候释放操作系统资源还不够。

特别有两个问题:

  1. 您可能会在 GC 有机会运行之前就达到操作系统限制。达到这样的限制不会像耗尽堆空间那样触发自动 GC。
  2. 即使您释放操作系统资源,您可能仍然拥有不会刷新的应用程序级缓冲区。

例如,Debian Linux 的默认打开文件限制为 1024,以防止行为不当的程序对自身进行 DoS 攻击。考虑这个程序,每次迭代最好只使用一个 FD:

import java.io.*;
class Foo {
public static void main(String[] args) throws Exception {
for(int i=0; i<2000; i++) {
FileInputStream fis = new FileInputStream("Foo.java");
}
}
}

运行它时会发生以下情况:

$ java Foo
Exception in thread "main" java.io.FileNotFoundException: Foo.java (Too many open files)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
at java.io.FileInputStream.<init>(FileInputStream.java:93)
at Foo.main(Foo.java:5)

如果您手动关闭该文件,则不会发生这种情况。

这是将字符串写入文件然后将其读回的程序的另一个示例:

import java.io.*;
class Foo {
static void writeConfig(String s) throws IOException {
BufferedWriter fw = new BufferedWriter(new FileWriter("config.txt"));
fw.write(s);
System.out.println("Successfully wrote config");
}
static String readConfig() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("config.txt"));
return reader.readLine();
}
public static void main(String[] args) throws Exception {
writeConfig("Hello World");
System.gc(); // Futile attempt to rely on the GC
String input = readConfig();
System.out.println("The config string is: " + input);
}
}

这是你得到的:

$ java Foo
Successfully wrote config
The config string is: null

写入的字符串没有进入文件。如果您关闭了 BufferedWriter,这将不是问题。

关于java - 为什么需要关闭 Java 中文件打开的连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55597683/

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