Java IOException“打开的文件太多" [英] Java IOException "Too many open files"

查看:57
本文介绍了Java IOException“打开的文件太多"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对多个文件进行一些文件 I/O(写入 19 个文件,确实如此).在给他们写了几百次之后,我得到了 Java IOException: Too many open files.但实际上我一次只打开了几个文件.这里有什么问题?我可以验证写入是否成功.

I'm doing some file I/O with multiple files (writing to 19 files, it so happens). After writing to them a few hundred times I get the Java IOException: Too many open files. But I actually have only a few files opened at once. What is the problem here? I can verify that the writes were successful.

推荐答案

在 Linux 和其他 UNIX/类 UNIX 平台上,操作系统对进程在任何给定时间可能具有的打开文件描述符的数量设置了限制.在过去,这个限制曾经是固定的1,而且相对较小.现在它要大得多(成百上千),并且受到每个进程的软"可配置资源限制.(查找内置的 ulimit shell ...)

On Linux and other UNIX / UNIX-like platforms, the OS places a limit on the number of open file descriptors that a process may have at any given time. In the old days, this limit used to be hardwired1, and relatively small. These days it is much larger (hundreds / thousands), and subject to a "soft" per-process configurable resource limit. (Look up the ulimit shell builtin ...)

您的 Java 应用程序必须超出每个进程的文件描述符限制.

Your Java application must be exceeding the per-process file descriptor limit.

你说你打开了 19 个文件,几百次后你得到一个 IOException 说打开的文件太多".现在这个特殊的异常只会在请求一个新的文件描述符时发生;即当您打开一个文件(或管道或套接字)时.您可以通过打印 IOException 的堆栈跟踪来验证这一点.

You say that you have 19 files open, and that after a few hundred times you get an IOException saying "too many files open". Now this particular exception can ONLY happen when a new file descriptor is requested; i.e. when you are opening a file (or a pipe or a socket). You can verify this by printing the stacktrace for the IOException.

除非您的应用程序以较小的资源限制运行(这似乎不太可能),否则它必须反复打开文件/套接字/管道,并且无法关闭它们.找出发生这种情况的原因,您应该能够弄清楚该怎么做.

Unless your application is being run with a small resource limit (which seems unlikely), it follows that it must be repeatedly opening files / sockets / pipes, and failing to close them. Find out why that is happening and you should be able to figure out what to do about it.

仅供参考,以下模式是一种写入文件的安全方式,可保证不会泄漏文件描述符.

FYI, the following pattern is a safe way to write to files that is guaranteed not to leak file descriptors.

Writer w = new FileWriter(...);
try {
    // write stuff to the file
} finally {
    try {
        w.close();
    } catch (IOException ex) {
        // Log error writing file and bail out.
    }
}

<小时>

1 - 硬连线,如编译到内核中.更改可用 fd 插槽的数量需要重新编译……并且可能导致可用于其他事情的内存减少.在 Unix 通常在 16 位机器上运行的日子里,这些事情真的很重要.

更新

Java 7 的方式更简洁:

The Java 7 way is more concise:

try (Writer w = new FileWriter(...)) {
    // write stuff to the file
} // the `w` resource is automatically closed 

<小时>

更新 2

显然,您在尝试运行外部程序时也会遇到打开的文件过多".基本原因如上所述.但是,您在 exec(...) 中遇到这种情况的原因是 JVM 正在尝试创建将连接到外部应用程序的标准输入/输出/错误的管道"文件描述符.

Apparently you can also encounter a "too many files open" while attempting to run an external program. The basic cause is as described above. However, the reason that you encounter this in exec(...) is that the JVM is attempting to create "pipe" file descriptors that will be connected to the external application's standard input / output / error.

这篇关于Java IOException“打开的文件太多"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆