我正在处理的应用程序突然崩溃了
java.io.IOException: ... Too many open files
据我了解,这意味着文件已打开但未关闭。
Stacktrace 当然是在事后发生的,只能帮助了解发生什么事件错误之前。
什么是搜索代码库以查找此问题的智能方法,该问题似乎仅在应用程序处于高压力负载下时才会发生。
我正在处理的应用程序突然崩溃了
java.io.IOException: ... Too many open files
据我了解,这意味着文件已打开但未关闭。
Stacktrace 当然是在事后发生的,只能帮助了解发生什么事件错误之前。
什么是搜索代码库以查找此问题的智能方法,该问题似乎仅在应用程序处于高压力负载下时才会发生。
用于 lsof -p pid
检查导致文件引用泄漏的原因;
用于ulimit -n
查看单个进程打开文件引用的限制;
检查你项目中的任何IO资源,是否及时释放? ,注意File
,,,,(和Http连接)都是IO资源。Process
Socket
有时,太多的线程也会导致这个问题。
什么操作系统?如果是 linux/mac,那么/proc 下的信息应该会有所帮助。在 Windows 上,使用Process Explorer。
至于搜索代码库,也许寻找捕获或引发的代码IOException
- 我认为已经捕获/引发这个的 I/O 方法很可能需要close()
调用。
您是否尝试过使用 jvisualvm(Java 5.0 及更高版本在 JDK bin 目录中)附加到正在运行的进程。您可以打开正在运行的进程并进行堆转储(如果您有较旧的 JDK,则需要使用 eclipse 或 intellij 或 netbeans 等进行分析)。
在 JDK 7 中,堆转储按钮位于“监视器”选项卡下。它将创建一个堆转储选项卡,“类”子选项卡,您可以检查并查看是否存在大量打开文件的任何类。另一个非常有用的功能是堆转储比较,因此您可以获取一个参考堆转储,让您的应用程序运行一下,然后再获取另一个堆转储并比较两者(比较链接在您获得的“[heapdump]”选项卡上当你拿一个时。java中还有一个标志用于在崩溃或OOM异常时进行堆转储,如果比较堆转储没有给你一个导致问题的明显类,你可以沿着这条路线走。另外,“实例”堆转储差异中的子选项卡将向您显示两个堆转储之间的时间分配的内容,这也可能有所帮助。
jvisualvm 是一个很棒的工具,但没有得到足够的提及。