【发布时间】:2010-02-16 12:45:16
【问题描述】:
我在 Java 中遇到了这个异常:
java.io.FileNotFoundException: (Too many open files)
我正在寻找解决此问题的方法。
这个错误显然表明 JVM 分配了太多句柄,而底层操作系统不会让它有更多。要么我在连接/流关闭不正确的地方出现泄漏。
此过程连续运行数天并最终引发异常。它在正常运行 12-14 天后反复发生。
你是怎么解决这个问题的?有没有办法在 JVM 中获取已分配句柄的列表或跟踪它何时达到一定数量?我很想把它们打印出来,看看它是如何生长的以及何时生长的。我不能使用分析器,因为它是一个生产系统并且在开发中难以重现它。有什么建议吗?
我正在监视空闲堆大小并在它接近 -Xmx 中指定的总数的 1% 时发出“警报”。我也知道,如果我的线程数达到 500 以上,那么肯定会失控。现在,有没有办法知道我的 JVM 从 OS 分配了 太多的句柄,并且没有返回它们,例如套接字、打开的文件等。如果我知道这些,我就会知道在哪里以及何时查看。
【问题讨论】:
-
你能提供更多关于JVM和操作系统的信息吗?另外,我建议您在开发环境中投入更多精力来重现这一点。这可能很麻烦,但是当您遇到此类问题时,尝试在生产系统上“观察和报告”可能需要更长的时间。
-
在运行虚拟化的 Linux 上确实会反复发生这种情况,我们真的无法通过运行 2 周的重负载测试来重现这种情况。不过,我还没有在 Windows 盒子上看到这种情况。没错,最好在 dev. 中捕获它,但我也希望在服务器本身中嵌入一些功能,以便将来进行自我监控。
-
重新编辑。我认为 JVM 无法告诉您它是如何打开任何文件的。这可能是 Sun 添加的一个不错的功能,但在此之前,您将不得不使用外部进程来告诉您。如果您在 JVM 中确实需要它,请编写一些执行 lsof 并返回结果的代码。此外,可以更改打开文件的限制。例如在 Linux 中,您可以修改 /etc/security/limits.conf 文件。
-
bramp,谢谢.. linux 可以授予单个进程的默认最大 nof 句柄是多少?我查看了我的默认 ubuntu 安装和 limits.conf 如果几乎是空的,我认为它使用了一些默认值..
-
回复我自己 - 默认为 1024