打开文件太多错误,但lsof显示合法数量的打开文件 [英] Too many open files error but lsof shows a legal number of open files

查看:1006
本文介绍了打开文件太多错误,但lsof显示合法数量的打开文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的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:

Here are key lines from /etc/security/limits.conf. They set the max files for a user at 500k:

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

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

I ran lsof to to count the number of files open -- both globally and by the jvm process. I examined counters in /proc/sys/fs. All seems OK. My process only has 4301 files open and the limit is 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服务器。我甚至重新启动,所以我很肯定这些参数正在被使用。

This is an Ubuntu 11.04 server. I have even rebooted so I am positive these parameters are being used.

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

I don't know if it's relevant, but the process is started by an upstart script, which starts the process using setuidgid, like this:

exec setuidgid username java $JAVA_OPTS -jar myprogram.jar

我缺少什么?

推荐答案

事实证明问题是我的程序是作为一个新贵的init脚本运行的,并且 exec 节不会调用shell。 ulimit ,limits.conf中的设置仅适用于shell中的用户进程。

It turns out the problem was that my program was running as an upstart init script, and that the exec stanza does not invoke a shell. ulimit and the settings in limits.conf apply only to user processes in a shell.

我通过将exec节更改为

I verified this by changing the exec stanza to

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

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

which runs java in username's default shell. That allowed the program to use as many open files as it needs.

已经看到它提到你也可以打电话给<在调用命令之前code> ulimit -n ;对于一个upstart脚本,我认为你会使用脚本节。

I have seen it mentioned that you can also call ulimit -n prior to invoking the command; for an upstart script I think you would use a script stanza instead.

我找到了比<$更好的诊断c $ c> lsof 为 ls / proc / {pid} / fd | wc -l <​​/ code>,获取打开文件描述符的精确计数。通过监控我可以看到故障发生在4096开放fds。我不知道4096来自哪里;它不在/ etc中;我猜它已编译到内核中。

I found a better diagnostic than lsof to be ls /proc/{pid}/fd | wc -l, to obtain a precise count of the open file descriptor. By monitoring that I could see that the failures occurred right at 4096 open fds. I don't know where that 4096 comes from; it's not in /etc anywhere; I guess it's compiled into the kernel.

这篇关于打开文件太多错误,但lsof显示合法数量的打开文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆