2017-07-11 726 views
2

我们的java应用程序在长时间运行后抛出“太多打开的文件”问题。 在调试问题时,看到有许多fds按照lsof输出打开。找到哪个线程导致太多的打开文件问题,为什么lsof输出中有重复的节点ID

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

--------------很少lsof的数据----- ------

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的根本原因。 在我们的应用程序中没有太多的文件读/写操作。有很多TCP消息使用apache mina框架在内部使用Nio从流中读取。

这是我的问题

  1. 我们已检查过的/ proc/PID /任务/文件夹。有很多文件夹。它是否对应于线程ID?但根据jstack,有141个线程,因为这个文件夹有209个子文件夹。
  2. 如何找到哪个线程导致fd泄漏?在我们的案例中,任务文件夹中的大部分文件夹对应于许多fds。即。/proc /进程/任务/线程ID/FD文件夹中有很多FD记录
  3. 什么是管的可能原因,并anon_inodes在lsof的
  4. 什么是FD型0000
  5. 所有anon_inode的意义与同一个节点ID 3042 。 这是什么意思?
+1

[Here](https://stackoverflow.com/questions/8170902/why-is-the-jdk-nio-using-so-many-anon-inode-file-descriptors)是一个相关的帖子/讨论。这种泄漏的常见原因是没有正确关闭和处理的插座和管道。这可能有助于随时监测计数并将增长与外部因素联系起来。 –

+0

@AxelKemper:在任何给定的时间内都会打开近12000个套接字,并且大多数处于TIMED_WAIT状态。那么我可以将此问题与TIMED_WAIT套接字关联吗? – Albin

+0

随时?系统重启后,我预计线性增长。 –

回答

1

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

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

0

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

  1. 我们启用strace的在我们的Linux服务器
  2. 我们做了strace的为两分钟的过程
  3. 我们可以找出线程ID导致问题
  4. 从jstack我们找到了线程类。
相关问题