jvm如何以及何时何地更改Linux的最大打开文件值? [英] How and when and where jvm change the max open files value of Linux?

查看:101
本文介绍了jvm如何以及何时何地更改Linux的最大打开文件值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在linux中,每个登录用户的每个进程的最大打开文件数是有限制的,如下所示:

In linux there is a limit for max open files for every process of each login user, as below:

$ ulimit -n
1024

当我学习java nio时,我想检查一下这个值.因为channel在Linux中也是一个文件,所以我编写了一个客户端代码来连续创建socketChannel,直到抛出以下异常为止:

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)

但是我发现它直到创建了约4085个socketChannel时,它都会引发此异常.该数字大于1024.有人告诉我jvm隐式更改了该值.我写了一个Java程序来执行ulimit命令,发现jvm确实改变了值.如下:

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

有人知道jvm在何时何地以及如何更改此值吗?是否存在一些系统日志来记录此更改,或者某些系统工具可以监视此更改?

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
...

下载openjdk,然后将其安装到热点目录

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;

然后重建这个openjdk,然后使用这个新的jdk执行上面的代码,您会发现输出为2048.

then rebuild this openjdk, then use this new jdk to execute above code, you'll find the output is 2048.

这篇关于jvm如何以及何时何地更改Linux的最大打开文件值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆