Linux – Max file descriptor limit not sticking

linux

Our cloud based systems use Java and require greater than 1024 for the max file descriptor limit. On one of our virtual systems, every time we try to make this change, I can get it to change and it will be persistent across the first reboot (have not tested multiple), but if we stop and start our java app, the limit seems to get reset to 1024.

System info:
Linux mx.xen16.node01002 3.1.0-1.2-xen #1 SMP Thu Nov 3 14:45:45 UTC 2011 (187dde0) x86_64 GNU/Linux

Here are the steps I took:

edited /etc/sysctl.conf and appended fs.file-max = 4096

Before applying, checked the limit for the process (PID 1530):

root 1530 6.7 31.0 1351472 165244 pts/0 Sl 17:12 0:58 java

cat /proc/1530/limits

Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             unlimited            unlimited            processes
Max open files            1024                 1024                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       16382                16382                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

Now I apply the change with:

sudo sysctl -p

fs.file-max = 4096 (ok it should be set)

I now do a reboot

When the system comes back up, the java app starts automatically and using the new PID I check the limits again.

Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             3818                 3818                 processes
Max open files            4096                 4096                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       3818                 3818                 signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

The limit is set correctly, however if I start and stop the java app, the limit defaults back to 1024. There is not an issue with the java app. This is one of SEVERAL identical cloud based systems around the world, each one a copy of this one. This VM resides at Gigatux. We have several other identical systems at Giga running the same OS, same version, and same app and app version. Only this one is behaving strangely. Please help.

* UPDATE *

I removed the statement from the end of the sysctl.conf per David's recommendation. If I issue ulimit -n, the limit is indeed set to 4092. If I look in /etc/security/limits.conf, you can see the limits configured here as well.

*               hard    nofile          4096
*               soft    nofile          4096

Yet if I restart the java process, it still defaults back to 1024.

agent@mx:~$ cat /proc/2432/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             unlimited            unlimited            processes
Max open files            1024                 1024                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       16382                16382                signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us
agent@mx:~$ echo -n $SHELL ' '  && ulimit -n
/bin/bash  4096

* UPDATE *

Ok, I think this may be fixed. I changed the following:

*               hard    nofile          4096
*               soft    nofile          4096

back to the following:

root               hard    nofile          4096
root               soft    nofile          4096

and the issue appears to be resolved

Best Answer

There's two places the limit gets set, you've changed one of them (sysctl) but you've forgotten that the shell environment that Java runs under also sets its own limit which may be equal to or less than the system limit:

composed-~$ echo -n $SHELL ' '  && ulimit -n
/usr/local/bin/bash  1024

So, figure out which shell Java gets launched from, and set the limit with the built in shell command. For example "ulimit" in bash.