调试“打开的文件太多”问题

时间:2013-04-11 15:20:06

标签: java ioexception

我正在处理的应用程序突然崩溃

java.io.IOException: ... Too many open files

据我所知,这意味着文件已打开但未关闭。

Stacktrace当然是在事后发生的,只能帮助理解发生了什么事件错误。

搜索代码库以找到此问题的智能方法是什么,只有当应用程序处于高压力负载时才会出现这种问题。

4 个答案:

答案 0 :(得分:12)

我认为使用专门为此目的设计的工具的最佳方式,例如this one

  

这个小Java代理是一个工具,可以跟踪JVM中何处/何时/谁打开文件。您可以让代理跟踪这些操作以了解访问模式或处理泄漏,并转储当前打开的文件列表以及打开它们的位置/时间/人员。

     

此外,在“太多打开文件”异常时,此代理将转储列表,以便您查找正在使用大量文件描述符的位置。

我似乎记得YourKit周围也有一些设施,但目前找不到任何具体信息。

答案 1 :(得分:11)

  1. 使用lsof -p pid检查导致文件引用泄漏的原因;

  2. 使用ulimit -n查看单个流程的已打开文件引用的限制;

  3. 检查项目中的所有IO资源,是否及时发布?请注意,FileProcessSocket(和Http连接)都是IO资源

  4. 有时,过多的线程也会导致这个问题。

答案 2 :(得分:3)

什么操作系统?如果它是linux / mac,那么information under /proc应该有所帮助。在Windows上,使用Process Explorer

就搜索代码库而言,可能会查找捕获或引发IOException的代码 - 我认为已经捕获/引发此问题的I / O方法很可能需要close()调用

答案 3 :(得分:3)

您是否尝试使用jvisualvm(JDK bin目录中的Java 5.0及更高版本)附加到正在运行的进程。您可以打开正在运行的进程并执行堆转储(如果您有较旧的JDK,则需要使用eclipse或intellij或netbeans等进行分析)。

在JDK 7中,堆转储按钮位于“监视器”选项卡下。它将创建一个堆转储选项卡,“Classes”子选项卡,您可以检查并查看是否存在大量打开文件的类。另一个非常有用的功能是堆转储比较,所以你可以进行引用堆转储,让你的应用程序运行一点然后再进行另一个堆转储并比较两者(要比较的链接在你的“[heapdump]”选项卡上)当你拿一个。在java中还有一个标志用于在崩溃或OOM异常时获取heapdump,如果比较堆转储没有给你一个导致问题的明显类,你可以沿着那条路走下去。另外,“Instances”堆转储差异中的子选项卡将显示在两个堆转储之间的时间内分配的内容,这也可能有所帮助。

jvisualvm是一个很棒的工具,没有得到足够的提及。