How and when and where jvm change the max open files value of Linux?

馋奶兔 提交于 2019-12-08 03:40:22

问题


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?


回答1:


$ 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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!