繁体   English   中英

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

[英]Getting too many file descriptor open, in java application while performing file operation

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

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

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

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

流是可关闭的对象,并且Files.list() 的 api 文档指出:

应该使用 try-with-resources 构造来确保在 stream 操作完成后调用流的关闭方法。

所以,你应该这样做:

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

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

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

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

Java 提供 AutoCloseable API 来处理外部资源释放,因为这个操作不能信任 GC:

  • GC 释放 java 托管 memory,不是外部资源
  • 无论如何,不能保证GC 清理时间。 它可能会在下一秒或下一分钟发生。 对于需要及时处理的资源是不可靠的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM