2015年8月28日金曜日

JavaVMがプロセスのMax open filesのソフトリミットを変更する件

JavaVMを起動するとそのプロセスのMax open filesのソフトリミット(soft limit:一般ユーザが変更できる上限値、ulimit -Snで参照可能)をハードリミット(hard limit:rootが変更できる上限値、ulimit -Hnで参照可能)まで引き上げます。

Ubuntu14.04LTSでは一般ユーザのMax open filesは以下のようにソフトリミット1,024、ハードリミット4,096になっています。


$ ps
  PID TTY          TIME CMD
 2447 pts/0    00:00:00 bash
 3766 pts/0    00:00:00 ps
$ cat /proc/2447/limits | grep 'Max open files'
Max open files            1024                 4096                 files   


以下のようなプログラムを作って実行、


$ cat > Test.java
public class Test {
    public static void main(String arvs[]) {
        try {
            while (true)
                Thread.sleep(1000);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
$ javac Test.java
$ java Test


同様に/procの下を確認してみると、両方とも4,096になっています。つまりソフトリミットがハードリミットまで引き上げられています。


$ ps -ef | grep Test
sofnec    4007  2200  0 14:37 pts/13   00:00:00 java Test
sofnec    4030  2447  0 14:37 pts/0    00:00:00 grep --color=auto Test
$ cat /proc/4007/limits | grep 'Max open files'
Max open files            4096                 4096                 files   


この件、古いJavaVMのドキュメントには-XX:MaxFDLimitオプションで説明されていますが(http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html)、最近のLinix版のもの(http://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html)にはこのオプションが書かれていません。

ところが、Linux 版のJava8で試したところ、このオプションが使えてしまいました。


$ java -XX:-MaxFDLimit Test


これで起動して別のターミナルで確認すると、以下のようにソフトリミットは変更されていません。


sofnec@cassandra1:~$ ps -ef | grep Test
sofnec    4387  2200  0 14:51 pts/13   00:00:00 java -XX:-MaxFDLimit Test
sofnec    4398  2447  0 14:51 pts/0    00:00:00 grep --color=auto Test
sofnec@cassandra1:~$ cat /proc/4387/limits | grep 'Max open files'
Max open files            1024                 4096                 files


でこの動き、Ubuntu14.04LTSのOpenJDKでも一緒でした。こちらについてはソースレベルで確認された方がいました。

http://stackoverflow.com/questions/30487284/how-and-when-and-where-jvm-change-the-max-open-files-value-of-linux

というわけで最初に書きましたがもう一度。

JavaVMはそのプロセスのMax open filesのソフトリミットをハードリミットまで引き上げますが、-XX:-MaxFDLimitオプションにより無効にできます。

(ドキュメントに書いといてよ...)