Java错误:打开的文件太多

时间:2012-12-04 15:36:01

标签: java

我编写了一个java代码,它是一个用于组合3种不同软件的包装器。我正常运行代码100,000次。在每次运行时,应该打开,重写和关闭不同的文件,其中所有文件都以正确的try和catch惯例发生。如果我在Linux服务器上运行代码,那就没问题了。但是,当我在1000的10s之后在我的mac上运行它时,出现太多打开文件的错误,并且随后在加载文件X和Y时出错,等等,程序终止。

我想补充一件事:代码运行1000次,然后设置被更改并再次进行1000次并重复此过程。因此,对于前4-5次,没有问题,而在6-7次(意味着6000次运行)之后会发生此错误。

2 个答案:

答案 0 :(得分:5)

最可能的解释是,您的Java应用程序中存在导致文件打开文件泄露的错误。避免此问题的方法是编写代码,以便文件句柄始终关闭; e.g。

    // Using the 'try with resource' construct
    try (Reader r = new FileReader(...)) {
        // use the reader
    } catch (IOException ex) {
        // ...
    }

    // Using classic try/catch/finally
    Reader r = null;
    try {
        r = new FileReader(...);
        // use the reader
    } catch (IOException ex) {
        // ...
    } finally {
        if (r != null) {
            try {
                r.close();
            } catch (IOException ex) {
                // ignore
            }
        }
    }

该程序很可能在一个操作系统而不是另一个操作系统上运行,因为两个系统上打开文件数量的限制是不同的。如果Java GC运行,它将关闭它通过相应句柄的终结器找到的任何无法访问的文件句柄。但是,这可能不会及时发生,以防止“太多文件打开”异常。


如果您的应用程序实际上需要同时打开大量文件,则需要提升限制。最好使用内置的ulimit shell,假设您使用的是基于UNIX的操作系统。

但请注意,仍然存在不可能超过的硬限制。我相信这也适用于Windows。

答案 1 :(得分:3)

您需要增加允许进程使用ulimit的文件数量限制,例如

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 71679
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 2048
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 71679
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

此计算机上的默认打开文件限制为2048。在另一台机器上,限制设置为364076;)

或者您必须减少使用量。这不是Java控制的东西,这是你必须控制的东西。