【问题标题】:Too many open files error but lsof shows a legal number of open files打开文件过多错误,但 lsof 显示打开文件的合法数量
【发布时间】:2012-01-25 23:08:06
【问题描述】:

我的 Java 程序失败了

Caused by: java.io.IOException: Too many open files
        at java.io.UnixFileSystem.createFileExclusively(Native Method)
        at java.io.File.createNewFile(File.java:883)...

这里是来自/etc/security/limits.conf 的关键行。他们将用户的最大文件设置为 500k:

root                     soft    nofile          500000
root                     hard    nofile          500000
*                        soft    nofile          500000
*                        hard    nofile          500000

我运行lsof 来计算打开的文件数——全局和 jvm 进程。我检查了/proc/sys/fs 中的计数器。一切似乎都很好。我的进程只打开了4301个文件,限制为500k:

:~# lsof | wc -l
5526
:~# lsof -uusername | wc -l
4301
:~# cat /proc/sys/fs/file-max
744363
:~# cat /proc/sys/fs/file-max
744363
:~# cat /proc/sys/fs/file-nr
4736    0       744363

这是一个 Ubuntu 11.04 服务器。我什至已经重新启动,所以我很肯定这些参数正在被使用。

我不知道它是否相关,但该进程是由一个 upstart 脚本启动的,该脚本使用 setuidgid 启动该进程,如下所示:

exec setuidgid username java $JAVA_OPTS -jar myprogram.jar

我错过了什么?

【问题讨论】:

  • 尝试更新你的堆空间并给它一个更大的最大值。不知道为什么这两者会相关,但我在无数不同的问题上都遇到了这个错误。
  • 很有趣,谢谢。但它已经是-Xmx5800m :)
  • 您在进程树的某个位置使用 ulimit 设置新限制?

标签: java linux


【解决方案1】:

事实证明,问题在于我的程序作为新贵初始化脚本运行,而exec 节没有调用 shell。 ulimit 和 limits.conf 中的设置仅适用于 shell 中的用户进程。

我通过将 exec 节更改为来验证了这一点

exec sudo -u username java $JAVA_OPTS -jar program.jar

在用户名的默认 shell 中运行 java。这使得程序可以根据需要使用尽可能多的打开文件。

have seen it mentioned,您也可以在调用命令之前调用ulimit -n;对于一个新贵的脚本,我认为你会使用 script 节。

我发现比lsof 更好的诊断是ls /proc/{pid}/fd | wc -l,以获得打开文件描述符的精确计数。通过监视,我可以看到故障发生在 4096 个打开的 fds 上。我不知道那个 4096 是从哪里来的;它不在 /etc 的任何地方;我猜它已经编译到内核中了。

【讨论】:

    【解决方案2】:

    我在服务器创建脚本的顶部有这个 bash 的 sn-p:

    # Jack up the max number of open file descriptors at the kernel
    echo "fs.file-max = 1000000" >> /etc/sysctl.conf
    invoke-rc.d procps start
    
    # Increase max open file descriptors for this process
    ulimit -n 1000000
    
    # And for future ones as well
    cat >> /etc/profile <<LIMITS
    ulimit -n 1000000
    LIMITS
    cat >> /etc/security/limits.conf <<LIMITS
    root - nofile 1000000
    LIMITS
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 2013-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多