【问题标题】:Too many open files, is my file-handling correct?打开的文件太多,我的文件处理是否正确?
【发布时间】:2021-09-15 13:27:11
【问题描述】:

我们定期运行以下代码 sn-p 并且每次运行访问数千个文件。系统有时会开始提及“打开的文件过多”。对Java不太熟悉,我想知道这段代码是否有问题。我了解 try-construction 始终负责关闭文件。还是应该添加 finally 以防止文件保持打开状态?

...
try 
 ( 
     FileInputStream fis = new FileInputStream(fileName);
     InputStreamReader isr = new InputStreamReader(fis);
     LineNumberReader in = new LineNumberReader(isr);
)
{
      if (in != null)
      {
            String strLine;
            while ((strLine = in.readLine()) != null)
            {
                  strLine = strLine.substring(3);
                  printLine(bw, strLine);
            }
      }
} catch (Exception e)
{
        e.printStackTrace(jcsErr);
}
...

【问题讨论】:

  • 如果您在 Unix 上运行,如操作系统 lsof 应该可以帮助您列出 Java 进程打开的文件。
  • 它的价值,无需检查in != null。在 Java 中,new 运算符 always 返回一个非空对象。
  • 谢谢,不知道。

标签: java file-handling


【解决方案1】:

system(而不是 Java)报告“打开的文件过多”时,您遇到了系统的限制(更准确地说,是您的操作系统的限制)配置)。

这样的代码 sn-p 是可以的,但是当在多线程程序中使用时,它仍然会导致报告的问题(1000 个线程每个读取文件都可以完成这项工作......)。

【讨论】:

  • 谢谢。代码 sn-p 被调用数千次,作为检查代码中其他地方报告的文件列表的子例程。难道是访问文件的过程如此之快,事情正在积累,是否与 tcp_keepalive_time、tcp_keepalive_intvl 和 tcp_keepalive_probes 等操作系统参数有关系?目前我们系统上的设置是 60s、75s 和 9。我假设,一旦在代码 sn-p 中访问和读取一个文件,它就会正确关闭(在 try 构造的 bc 中,我们没有明确表示关闭流)。
  • 但是在运行代码的同时查看我们Linux系统上lsof的输出,我们看到系统上有很多与java-proces的特定PID相关的打开文件,还有半开的连接和许多很多文件都声明“无法识别协议”。
  • 一段时间后(大约 25-30 分钟),我们看到打开文件的数量正常化。但是,当我们在上次运行后的较早时间再次启动代码时,打开的文件会累积,最终运行到超过操作系统设置 (ulimit) 的级别,并报告打开的文件过多。
  • 我记得它们是一个错误,导致文件被 JVM 保持打开一段时间,尽管 Java 程序已经关闭了它们。但我不记得这是否已经修复和/或是否有办法绕过它。我什至不记得这是一个普遍问题还是仅存在于某些 Linux/UNIX 版本和/或 JVM 上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-04
  • 1970-01-01
  • 2015-12-09
  • 1970-01-01
相关资源
最近更新 更多