打开的文件太多,但是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:

 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服务器。 我甚至重新启动,所以我积极使用这些参数。

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

 exec setuidgid username java $JAVA_OPTS -jar myprogram.jar 

我错过了什么?

Solutions Collecting From Web of "打开的文件太多,但是lsof显示打开文件的合法数量"

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

我通过更改exec节来证实这一点

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

它在用户名的默认shell中运行java。 这允许程序使用尽可能多的打开的文件,因为它需要。

我已经看到它提到你也可以在调用命令之前调用ulimit -n ; 对于一个暴发户脚本,我认为你会使用script节代替。

我发现比lsof更好的诊断是ls /proc/{pid}/fd | wc -l ls /proc/{pid}/fd | wc -l ,以获得打开文件描述符的精确计数。 通过监控我可以看到,失败发生在4096开放的FDS。 我不知道4096从哪里来, 它不在/ etc在任何地方; 我想这是编译进内核。

我在服务器创建脚本的顶部有这个bash片段:

 # 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