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

Java 调试;“打开的文件太多”;问题,java,ioexception,Java,Ioexception,我正在开发的应用程序突然崩溃了 java.io.IOException: ... Too many open files 据我所知,这意味着文件是打开的,而不是关闭的 Stacktrace当然发生在事件发生之后,并且只能帮助理解发生错误之前的事件 什么是一种智能的方法来搜索你的代码库来发现这个问题,而这个问题似乎只有在应用程序处于高压力负载时才会发生。什么操作系统?如果是linux/mac,那么应该有帮助。在Windows上,使用 至于搜索代码库,可能要寻找捕获或引发IOException——

我正在开发的应用程序突然崩溃了

java.io.IOException: ... Too many open files
据我所知,这意味着文件是打开的,而不是关闭的

Stacktrace当然发生在事件发生之后,并且只能帮助理解发生错误之前的事件


什么是一种智能的方法来搜索你的代码库来发现这个问题,而这个问题似乎只有在应用程序处于高压力负载时才会发生。

什么操作系统?如果是linux/mac,那么应该有帮助。在Windows上,使用


至于搜索代码库,可能要寻找捕获或引发
IOException
——我认为已经捕获/引发该异常的I/O方法很可能需要调用
close()

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

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

此外,在出现“打开的文件太多”异常时,此代理将转储列表,使您能够找出大量文件描述符的使用位置

我似乎还记得在这附近有一些设施,但目前找不到任何具体信息

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

  • 使用
    ulimit-n
    查看单个进程打开的文件引用的限制

  • 检查项目中的任何IO资源,它们是否及时发布?请注意,
    文件
    过程
    套接字
    (以及Http连接)都是IO资源

  • 有时,线程过多也会导致此问题


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

    在JDK 7中,堆转储按钮位于“监视器”选项卡下。它将创建一个堆转储选项卡,“类”子选项卡,您可以检查并查看是否存在大量打开文件的类。另一个非常有用的功能是堆转储比较,因此您可以获取一个引用堆转储,让您的应用程序运行一段时间,然后获取另一个堆转储并比较两者(要比较的链接位于“[heapdump]”标签。java中还有一个标志,用于在崩溃或OOM异常时执行heapdump。如果比较堆转储并没有给出导致问题的明显类,则可以使用该标志。此外,“实例”堆转储差异中的子选项卡将显示在两个堆转储之间分配的时间,这也可能会有所帮助


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

    您是在多线程处理文件,还是在同一个线程上完成?您是否考虑过通过并发限制来管理工作负载?@christopher我在多线程处理文件。这个问题只在我使用多线程时出现。我有一个作业,并仅旋转线程数以匹配设备上的内核数(例如4个)因此,在任何给定时间只有4个线程处理作业队列。而且作业非常快。有什么想法吗?什么是并发限制?根据
    lsof-p pid
    我现在打开了3000个文件,而
    ulimit-n
    是2560。可能第一个命令的计数与此hel中的文件引用+1不同ped让我调试一个android应用程序,该应用程序的Process.Runtime.exec()使用了系统的ping。我必须在waitFor()之后调用Process.destroy()来修复它。你知道如何在android应用程序上使用该工具吗?