为什么我需要在资源上使用 .close()

why do i ever need to use .close() on resources

我知道这可能会遭到反对,这让我很困扰

我已经阅读了所有关于 .close() 方法的帖子,例如

explain the close() method in Java in Layman's terms

Why do I need to call a close() or shutdown() method?

我有这些问题可能看起来太琐碎了

1.what 这个词 'resource' 的确切含义是什么(它是文件还是 'FileWriter' 对象还是其他东西)(尽量解释得尽可能广泛)

让我们考虑以下代码

import java.io.*;
public class characterstreams
{
    public static void main(String []args) throws Exception
    {
        File f=new File("thischaracter.txt");
        FileWriter fw=new FileWriter(f);
        char[] ch={'a','c','d'};
        fw.write('a');
        fw.write(ch);
        fw.write("aaaa aaaaa aaaaaaa");
        fw.flush();
        FileReader fr=new FileReader(f);
        int r=fr.read();
        System.out.println(r);
        char[] gh=new char[30];
        System.out.println(fr.read(gh));
    }
}

编译执行后

G:/>java characterstreams

假设资源是下面的FileWriter(因为我还没有得到资源的含义)

JVM 启动并打开所谓的资源然后执行完成,然后 JVM 在执行后关闭

2.it 解锁它打开的资源,因为它 运行 不正确(如果我错了请纠正我)

G:/>

此时JVM不是运行

3.before 关闭,垃圾收集器被调用对吗?(如果错误请纠正我)所以 FileWriter 对象被销毁 那为什么我们要关闭我们已经打开的所有资源

4.again 我读到 'resources get leaked' 这是什么意思..?

resource 表示 JVM and/or 操作系统为您提供所需功能所需的任何东西。

以你为例。如果你打开一个FileWriter一般的操作系统(取决于操作系统,文件系统等)就可以了(假设你想把一个文件写入光盘,比如HDD/SDD)

  1. 为请求的文件名创建一个目录条目
  2. 创建一个数据结构来维护对文件的写入过程
  3. 分配磁盘space如果你真的向文件写入数据

(注意:这不是一个详尽的列表)

对于您打开进行写入的任何文件,该点都将完成。如果你不关闭 resource 所有这些都保留在内存中,并且仍然由操作系统维护。

假设您的应用程序 运行ning 了很长时间并且不断打开文件。操作系统允许您保持打开的打开文件数量是有限的(具体数量取决于操作系统、配额设置等)。如果资源耗尽,某些事情会出现意外或失败。

在下面找到 Linux 上的一个小演示。

public static void main(String[] args) throws IOException {
    List<OutputStream> files = new ArrayList<>();
    for (int i = 0; i < 1000; i++) {
        files.add(Files.newOutputStream(Paths.get("/tmp/demo." + i), 
                StandardOpenOption.CREATE));
    }
}

代码打开一千个文件进行写入。

假设您打开文件的限制是 1024

ulimit -n
1024

您 运行 代码段,它将生成 1000 个文件 /tmp/demo.*

如果打开文件的限制仅为 100,则代码将失败

ulimit -n 100
java.nio.file.FileSystemException: /tmp/demo.94: Too many open files

(之前失败是因为JVM本身有一些打开的文件)

为防止此类问题(资源不足),您应该关闭不再需要写入的文件。如果您不在 Java(close()) 中执行此操作,操作系统也不知道是否可以释放内存等并用于另一个请求。