查找哪个线程导致过多的打开文件问题,以及为什么在lsof输出

时间:2017-07-11 15:12:47

标签: java performance lsof

我们的java应用程序正在抛出太多打开的文件"运行很长时间后发出问题。 调试问题后,可以看到根据lsof输出打开了很多fds。

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

698962

# lsof -p pid | grep "anon_inode" | wc -l
  

349481

--------------很少有数据-----------

COMMAND   PID  USER   FD  TYPE             DEVICE SIZE/OFF       NODE NAME
java    23994  app 464u  0000                0,9        0       3042 anon_inode
java    23994  app 465u  0000                0,9        0       3042 anon_inode
java    23994  app 466r  FIFO                0,8      0t0  962495977 pipe
java    23994  app 467w  FIFO                0,8      0t0  962495977 pipe
java    23994  app 468r  FIFO                0,8      0t0  963589016 pipe
java    23994  app 469w  FIFO                0,8      0t0  963589016 pipe
java    23994  app 470u  0000                0,9        0       3042 anon_inode
java    23994  app 471u  0000                0,9        0       3042 anon_inode

如何找到FIFO和0000类型的许多开放FD的根本原因。 我们的应用程序中没有很多文件读/写。使用内部使用Nio的apache mina框架从流中读取了如此多的TCP消息。

这些是我的问题

  1. 我们检查了/ proc / pid / task /文件夹。有很多文件夹。它是否与线程ID相对应?但是根据jstack,有141个线程,因为这个文件夹有209个子文件夹。
  2. 如何找到导致fd泄漏的线程?在我们的例子中,任务文件夹中的大多数文件夹对应于许多fds。即。 / proc / pid / task / threadid / fd文件夹有很多fd记录
  3. lsof
  4. 中pipe和anon_inodes的可能原因是什么?
  5. FD type 0000
  6. 的含义是什么?
  7. 所有anon_inode都具有相同的节点ID 3042.这是什么意思?

2 个答案:

答案 0 :(得分:1)

最可能的是你打开资源然后没有正确关闭它们。确保使用适当的方法,例如try-with-resources或try-finally块来整理。

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

答案 1 :(得分:1)

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

  1. 我们在linux服务器上启用了strace
  2. 我们确实为这个过程做了几分钟
  3. 我们可以识别导致问题的线程ID
  4. 从jstack我们找到了线程类。