java - 在执行文件操作时在 java 应用程序中打开太多文件描述符

标签 java linux ubuntu

通过使用 files.list() java.nio.file.Files的API当我打开目录以查找文件时,我正在打开目录的 FD。
那么任何人都可以帮助为什么这个 API 会导致这样的问题吗?

因为在 Object[] 的方法 block 结束实例之后路径,必须由垃圾收集器清除,并且文件描述符应自动关闭。

我的应用程序在 Ubuntu 上运行。

import java.nio.file.Files;
Object[] paths=Files.list(dir.path)
         .filter(p -> p.getFileName().toString().contains(".txt")).toArray();

最佳答案

流是可关闭的对象,api documentation of Files.list()状态:

the try-with-resources construct should be used to ensure that the stream's close method is invoked after the stream operations are completed.



所以,你应该这样做:

final Path[] paths;
try (Stream<Path> dirList = Files.list(dir.path)) {
    paths = dirList.filter(...).toArray(size -> new Path[size]);
}

一般来说,我建议你检查从路径获得的任何对象,如果 AutoCloseable,则用 try-with-resource 封装它。没有它,Java 不知道何时关闭相关的系统资源。

如果您有 too many files opened您粘贴的代码行出错,它可能是您程序中的另一个文件操作也没有正确关闭。在这种情况下,您可以使用 IDE 检查工具或其他工具(如 spotBugs、sonar 等)来查找有问题的语句。

编辑 :Files.list返回一个延迟填充的列表。这意味着java将保持与操作系统的连接,并在用户浏览目录时查询目录内容。流应该被关闭,所以一旦你结束了对它的迭代,操作系统资源就会被释放。

Java 提供了 AutoCloseable API 来处理外部资源释放,因为 GC 不能被信任用于这个操作:
  • GC释放java托管内存,不是 外部资源
  • 反正有不保证关于 GC 清洗时间。它可能会在下一秒或下一分钟发生。对于需要及时处理的资源是不可靠的。

  • 示例:如果将外部资源清理委托(delegate)给 GC,当 JVM 突然崩溃时会出现严重问题:所有等待垃圾回收的资源都无法正常释放。
    使用显式构造,您可以确保所有打开的资源都已尽快关闭,并在发生崩溃时减少可能损坏的资源的数量。

    关于java - 在执行文件操作时在 java 应用程序中打开太多文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61817591/

    相关文章:

    linux - 设备上没有剩余空间 - Ubuntu问题

    java - 升级到 Ubuntu 14.04 后,JRE 在 Eclipse 中崩溃

    ubuntu - puppet 目录运行错误 SERVER : Not authorized to call find on/<path/to/my/file> 上的错误 400

    java - 当按钮似乎是从 JavaScript 生成时,如何使用 Selenium 访问按钮

    java - Spring Boot Spark 应用程序

    c - 是否可以在 C Linux 的多线程应用程序中使用多个计时器?

    linux - 一个 SSH key 适用于多个 Ubuntu 服务器 + Windows + Teamcity

    java - String的split方法可能出错

    java - 静态错误和主要问题

    linux - E : Some index files failed to download. 它们已被忽略,或使用旧的代替