使用lsof对“打开的文件太多”进行故障排除

时间:2013-04-11 18:45:35

标签: java ioexception lsof

我在Linux上使用PID 25426运行Java应用程序。运行lsof -p 25426时,我注意到:

java    25426 uid  420w  FIFO                0,8      0t0 273664482 pipe
java    25426 uid  421r  FIFO                0,8      0t0 273664483 pipe
java    25426 uid  461r  FIFO                0,8      0t0 273622888 pipe
java    25426 uid  463w  FIFO                0,8      0t0 273633139 pipe
java    25426 uid  464r  FIFO                0,8      0t0 273633140 pipe
java    25426 uid  465r  FIFO                0,8      0t0 273622889 pipe
java    25426 uid  471w  FIFO                0,8      0t0 273623682 pipe
java    25426 uid  472r  FIFO                0,8      0t0 273633141 pipe

如何解释这个结果?

我正在解决有太多打开文件的问题并尝试了解此观察是否相关。

随着应用程序继续运行,pipe个条目的数量会有所不同(上下移动)。

1 个答案:

答案 0 :(得分:18)

定义

  
      
  • java - 打开文件的过程。
  •   
  • 25426 - 这应该是真正的PID。如果没有,请通过发布标题告诉我们它是什么。
  •   
  • 420 w - 文件描述符编号后跟打开的模式。 (读/写)
  •   
  • 0,8 - 主要次要设备识别。
  •   
  • 273664482 - 文件的inode。
  •   
  • pipe - 在您的应用程序中打开的FIFO管道。
  •   

解释

您没有关闭所有流。在读取或写入模式下有许多打开文件描述符正在写入未命名的管道。这种情况最常见的情况是,当人们使用Runtime.getRuntime.exec()然后继续保持与流程关联的流打开时。您可以将公共IO工具库用于close them,也可以close them yourself

    try
    {
        p = Runtime.getRuntime().exec("something");
    }
    finally
    {
        if (p != null)
        {
            IOUtils.closeQuietly(p.getOutputStream());
            IOUtils.closeQuietly(p.getInputStream());
            IOUtils.closeQuietly(p.getErrorStream());
        }
    }

如果这不是问题,您需要深入研究代码库并确定泄漏流的位置并插入它们。