Files.walkFileTree 使用自定义 FileVisitor 泄漏目录描述符

莱昂茨

我在我的应用程序中遇到了一个奇怪的错误。我已经通过解决方法解决了它,但我仍然很好奇为什么会发生这个错误。

下面给出了一个自定义 FileVisitor 的示例,该示例正在删除它遍历的空目录。如果目录不为空,并且它仍然遍历这些目录,它将泄漏目录描述符。如果我lsof与应用程序的 PID 一起使用,它将显示一堆指向相同目录的描述符,即它遍历的目录。

private String getOldestFile() {
    fileVisitor.clearOldestFile();

    try {
        // FIXME: this was throwing FileSystemException: Too many open files after some time running. Leaking file descriptors!!
        Files.walkFileTree(Paths.get(csvPath), fileVisitor);
    } catch (IOException e) {
        e.printStackTrace();
    }

    return fileVisitor.getOldestFile().toString();
}

class CustomFileVisitor extends SimpleFileVisitor<Path> {
    private Path oldestFile = null;

    Path getOldestFile() {
        return oldestFile;
    }

    void clearOldestFile() {
        oldestFile = null;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        if (attrs.isDirectory())
            return FileVisitResult.CONTINUE;

        if (oldestFile == null)
            oldestFile = file;

        if (oldestFile.compareTo(file) > 0)
            oldestFile = file;

        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        if (dir.equals(Paths.get(csvPath)))
            return FileVisitResult.CONTINUE;

        if (Files.list(dir).collect(Collectors.toList()).size() == 0)
            Files.delete(dir); // throws an exception if folder is not empty -> mustn't delete folder with files

        return FileVisitResult.CONTINUE;
    }
}

CustomFileVisitor 仅在外部类中创建一次,并且该函数会定期调用,例如 filename = getOldestFile();

编辑:发布lsof -p {PID}输出。一开始,我在这个中找到了PID

这就是lsof -p {PID}输出的样子,只有数千行。“/home/leon/Development/data/”是 Files.walkFileTree 的输入。

java    14965 leon  285r      DIR                8,2     4096  1970798 /home/leon/Development/data/2017
java    14965 leon  286r      DIR                8,2     4096  1970799 /home/leon/Development/data/2017/10
java    14965 leon  287r      DIR                8,2     4096  1970799 /home/leon/Development/data/2017/10
java    14965 leon  288r      DIR                8,2    36864  1970800 /home/leon/Development/data/2017/10/17
java    14965 leon  289r      DIR                8,2    36864  1970800 /home/leon/Development/data/2017/10/17
java    14965 leon  290r      DIR                8,2     4096  1970798 /home/leon/Development/data/2017
java    14965 leon  291r      DIR                8,2     4096  1970798 /home/leon/Development/data/2017
java    14965 leon  292r      DIR                8,2     4096  1970799 /home/leon/Development/data/2017/10
java    14965 leon  293r      DIR                8,2     4096  1970799 /home/leon/Development/data/2017/10
java    14965 leon  294r      DIR                8,2    36864  1970800 /home/leon/Development/data/2017/10/17
java    14965 leon  295r      DIR                8,2    36864  1970800 /home/leon/Development/data/2017/10/17

编辑2:我已经成功地隔离问题这一行:Files.list(dir).collect(Collectors.toList()).size() == 0这不应该被垃圾收集吗?

托马斯

Files#list()文档

返回的流封装了一个DirectoryStream. 如果需要及时处理文件系统资源,则应使用 try-with-resources 构造以确保在流操作完成后调用流的 close 方法。

最终,流将被垃圾回收,但不会立即被回收。所以在这种情况下你必须自己管理它。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

ioutil是否使用过多的文件描述符/泄漏?

来自分类Dev

Java 7 walkFileTree在目录上调用visitFile

来自分类Dev

在哪里可以找到有关自定义USB描述符类型的信息

来自分类Dev

在Swift中为iOS字体描述符添加自定义权重

来自分类Dev

c ++:让用户进程写入LOCAL_SYSTEM命名管道-自定义安全描述符

来自分类Dev

将值从自定义HttpControllerSelector和HttpActionSelector转发到其描述符

来自分类Dev

在哪里可以找到有关自定义USB描述符类型的信息

来自分类Dev

Mave-assembly-plugin:自定义描述符以排除文件夹

来自分类Dev

c ++:让用户进程写入LOCAL_SYSTEM命名管道-自定义安全描述符

来自分类Dev

将值从自定义HttpControllerSelector和HttpActionSelector转发到其描述符

来自分类Dev

泄漏文件描述符

来自分类Dev

使用自定义目录作为“ templatetags”

来自分类Dev

使用BOWImgDescriptorExtractor重用描述符

来自分类Dev

定义全局描述符表有什么用?

来自分类Dev

如何使用setuptools安装在自定义目录中?

来自分类Dev

使用自定义目录进行apt-get?

来自分类Dev

使用自定义目录进行apt-get?

来自分类Dev

使用自定义分隔符Excel保存文件

来自分类Dev

使用pyparsing的自定义分隔符

来自分类Dev

使用自定义运算符减少OpenMP SIMD

来自分类Dev

使用自定义换行符加载CSV

来自分类Dev

使用自定义分隔符读取文件

来自分类Dev

使用合并的自定义更改运算符

来自分类Dev

使用表中的自定义值填充占位符

来自分类Dev

结合使用自定义运算符

来自分类Dev

使用自定义分隔符Excel保存文件

来自分类Dev

C ++:使用自定义==运算符的find()

来自分类Dev

如何使用自定义标识符启动实例

来自分类Dev

如何使用自定义分隔符货币值?

Related 相关文章

  1. 1

    ioutil是否使用过多的文件描述符/泄漏?

  2. 2

    Java 7 walkFileTree在目录上调用visitFile

  3. 3

    在哪里可以找到有关自定义USB描述符类型的信息

  4. 4

    在Swift中为iOS字体描述符添加自定义权重

  5. 5

    c ++:让用户进程写入LOCAL_SYSTEM命名管道-自定义安全描述符

  6. 6

    将值从自定义HttpControllerSelector和HttpActionSelector转发到其描述符

  7. 7

    在哪里可以找到有关自定义USB描述符类型的信息

  8. 8

    Mave-assembly-plugin:自定义描述符以排除文件夹

  9. 9

    c ++:让用户进程写入LOCAL_SYSTEM命名管道-自定义安全描述符

  10. 10

    将值从自定义HttpControllerSelector和HttpActionSelector转发到其描述符

  11. 11

    泄漏文件描述符

  12. 12

    使用自定义目录作为“ templatetags”

  13. 13

    使用BOWImgDescriptorExtractor重用描述符

  14. 14

    定义全局描述符表有什么用?

  15. 15

    如何使用setuptools安装在自定义目录中?

  16. 16

    使用自定义目录进行apt-get?

  17. 17

    使用自定义目录进行apt-get?

  18. 18

    使用自定义分隔符Excel保存文件

  19. 19

    使用pyparsing的自定义分隔符

  20. 20

    使用自定义运算符减少OpenMP SIMD

  21. 21

    使用自定义换行符加载CSV

  22. 22

    使用自定义分隔符读取文件

  23. 23

    使用合并的自定义更改运算符

  24. 24

    使用表中的自定义值填充占位符

  25. 25

    结合使用自定义运算符

  26. 26

    使用自定义分隔符Excel保存文件

  27. 27

    C ++:使用自定义==运算符的find()

  28. 28

    如何使用自定义标识符启动实例

  29. 29

    如何使用自定义分隔符货币值?

热门标签

归档