java - 查找哪个线程导致打开文件过多问题以及为什么在 lsof 输出中出现重复的节点 ID

标签 java performance lsof

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

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

698962

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

349481

------------少量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 的根本原因。 在我们的应用程序中发生的文件读/写并不多。使用内部使用 Nio 的 apache mina 框架从流中读取了如此多的 TCP 消息。

这些是我的问题

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

最佳答案

最有可能的情况是您正在打开资源,然后没有正确关闭它们。确保使用适当的方法(例如 try-with-resources 或 try-finally block )进行整理。

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

关于java - 查找哪个线程导致打开文件过多问题以及为什么在 lsof 输出中出现重复的节点 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45038400/

相关文章:

java regex - 搜索两次出现的搜索字符之间的空内容

java - MalformedURLException 虽然我已经用 %20 替换了空格

java - C++ 相当于 Java 的 this.getClass().getSimpleName();

C++ 性能 std::array 与 std::vector

linux - 如何记录24小时内的文件访问情况?

Java spark 框架启用日志记录

python - 是否有函数调用可以替代此代码中的 for 循环?

sql - 如何使用日期 GROUP BY 加速 SQL 查询?

ftp - 验证ftp是否完整?

parsing - 忽略文件中的目录