Java 查找导致打开的文件过多问题的线程以及lsof输出中重复节点ID的原因

Java 查找导致打开的文件过多问题的线程以及lsof输出中重复节点ID的原因,java,performance,lsof,Java,Performance,Lsof,我们的java应用程序在运行了很长时间后出现了“打开的文件太多”的问题。 在调试该问题时,可以看到根据lsof输出打开了很多FD # lsof -p pid | grep "pipe" | wc -l 698962 349481 --------------数据量很少----------- 命令PID用户FD类型设备大小/关闭节点名称 java 23994应用程序464u 0000 0,9 0 3042 anon_inode java 23994应用程序465u 0000 0,9 0 3042

我们的java应用程序在运行了很长时间后出现了“打开的文件太多”的问题。 在调试该问题时,可以看到根据lsof输出打开了很多FD

# lsof -p pid | grep "pipe" | wc -l
698962

349481

--------------数据量很少-----------

命令PID用户FD类型设备大小/关闭节点名称
java 23994应用程序464u 0000 0,9 0 3042 anon_inode
java 23994应用程序465u 0000 0,9 0 3042 anon_inode
java 23994 app 466r先进先出0,8 0t0 962495977管道
java 23994 app 467w先进先出0,8 0t0 962495977管道
java 23994 app 468r先进先出0,8 0t0 963589016管道
java 23994 app 469w FIFO 0,8 0t0 963589016管道
java 23994应用程序470u 0000 0,9 0 3042 anon_inode
java 23994应用程序471u 0000 0,9 0 3042 anon_inode
如何找到FIFO和0000类型的许多打开FD的根本原因。 我们的应用程序中没有太多的文件读/写操作。使用内部使用Nio的ApacheMina框架从流中读取的TCP消息太多了。

这些是我的问题

  • 我们已选中/proc/pid/task/folder。有许多文件夹。它是否对应于线程ID?但是根据jstack,有141个线程,其中这个文件夹有209个子文件夹
  • 如何找到导致fd泄漏的线程?在我们的例子中,任务文件夹中的大多数文件夹对应于许多FD。ie./proc/pid/task/threadid/fd文件夹有许多fd记录
  • lsof中出现管道和非管道索引节点的可能原因是什么
  • FD类型0000的含义是什么
  • 所有anon_inode都具有相同的节点id 3042。这是什么意思

  • 最可能的情况是,您正在打开资源,但没有正确地关闭它们。请确保使用适当的方法,如使用资源进行尝试或最终尝试块进行整理


    要找到问题,您应该将所有IO路由到一个类中,然后跟踪打开和关闭,甚至可能记住堆栈跟踪。然后,您可以查询该问题并查看泄漏资源的位置。

    我们发现了问题。有一个创建org.apache.mina.transport.socket.nio.NioSocketConnector的代码流,但在某些情况下没有关闭。为了找到问题,我们做了以下工作

  • 我们在linux服务器中启用了strace
  • 我们花了几分钟的时间仔细观察这个过程
  • 我们可以识别导致问题的线程id
  • 从jstack中,我们找到了线程类

  • 是相关的帖子/讨论。此类泄漏的常见原因是未正确关闭和处理的插座和管道。它可能有助于监控一段时间内的计数,并将增长与外部因素联系起来。@Axelkeper:在任何给定时间都有近12000个插槽处于打开状态,大多数处于定时等待状态。那么我可以随时将这个问题与定时等待套接字联系起来吗?我预计系统重启后会出现线性增长。
    # lsof -p pid | grep "anon_inode" | wc -l