使用 lsof 解决“打开的文件太多”问题定义解释

2022-09-04 19:55:08

我有一个Java应用程序在Linux上运行,PID 25426。跑步时,我注意到: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

定义

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

解释

您没有关闭所有流。在读取或写入模式下,有许多打开的文件描述符正在写入未命名的管道。这种情况最常见的情况是,当人们使用 Runtime.getRuntime.exec() 然后继续保持与进程关联的流处于打开状态时。您可以使用共享资源 IO utils 库来关闭它们,也可以自己关闭它们

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

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


答案 2

推荐