我编写了一个java代码,它是一个用于组合3种不同软件的包装器。我正常运行代码100,000次。在每次运行时,应该打开,重写和关闭不同的文件,其中所有文件都以正确的try和catch惯例发生。如果我在Linux服务器上运行代码,那就没问题了。但是,当我在1000的10s之后在我的mac上运行它时,出现太多打开文件的错误,并且随后在加载文件X和Y时出错,等等,程序终止。
我想补充一件事:代码运行1000次,然后设置被更改并再次进行1000次并重复此过程。因此,对于前4-5次,没有问题,而在6-7次(意味着6000次运行)之后会发生此错误。
答案 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控制的东西,这是你必须控制的东西。