In linux there is a limit for max open files for every process of each login user, as below:
$ ulimit -n
1024
When I study java nio, I'd like to check this value. Because channel also is a file in Linux,I wrote a client code to create socketChannel continuely until throwing below exception:
java.net.SocketException: Too many open files
at sun.nio.ch.Net.socket0(Native Method)
at sun.nio.ch.Net.socket(Net.java:423)
at sun.nio.ch.Net.socket(Net.java:416)
at sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:104)
at sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:60)
at java.nio.channels.SocketChannel.open(SocketChannel.java:142)
But I found it till created about 4085 socketChannel, it will throw this exception. This number is more than 1024. Somebody told me jvm changed the value implicitly. And I wrote a java program to execute ulimit command, and found jvm do change the value. As below:
String [] cmdArray = {"sh","-c","ulimit -n"};
Process p = Runtime.getRuntime().exec(cmdArray);
BufferedInputStream in = new BufferedInputStream(p.getInputStream());
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len)); //4096
Does anybody know when and where and how jvm changes this value? Does exist some sys log to record this change or some sys tool could monitor this change?
$ strace -f -o HelloWorld.strace java HelloWorld
Hello World!
$ vi HelloWorld.strace
...
16341 getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0
16341 setrlimit(RLIMIT_NOFILE, {rlim_cur=4*1024, rlim_max=4*1024}) = 0
...
Download openjdk, then cd into hotspot dir,
$ grep -r setrlimit
...
src/os/linux/vm/os_linux.cpp: status = setrlimit(RLIMIT_NOFILE, &nbr_files);
...
$ vi src/os/linux/vm/os_linux.cpp
...
if (MaxFDLimit) {
// set the number of file descriptors to max. print out error
// if getrlimit/setrlimit fails but continue regardless.
struct rlimit nbr_files;
int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode))
perror("os::init_2 getrlimit failed");
} else {
nbr_files.rlim_cur = nbr_files.rlim_max;
status = setrlimit(RLIMIT_NOFILE, &nbr_files);
if (status != 0) {
if (PrintMiscellaneous && (Verbose || WizardMode))
perror("os::init_2 setrlimit failed");
}
}
...
If you modify above code, e.g.
//nbr_files.rlim_cur = nbr_files.rlim_max;
nbr_files.rlim_cur = 2048;
then rebuild this openjdk, then use this new jdk to execute above code, you'll find the output is 2048.
来源:https://stackoverflow.com/questions/30487284/how-and-when-and-where-jvm-change-the-max-open-files-value-of-linux