linux系统中如何监控(java)进程隐式执行或调用的系统命令(如ulimit)?

zgw06629 发布于 2015/05/28 22:25
阅读 817
收藏 1

终端中执行查询最大打开文件数:

$ ulimit -n
1024

java程序中通过Runtime来调用上述命令:

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改变了该值。但如何确定呢? 又没有类似Wireshark的工具可以抓包分析进入main方法前是否执行了ulimit命令? 搜索openjdk 源码(grep -r ulimit)也没有发现ulimit -n 4096这样的的代码;也不知在何处加断点?

问如何确定jvm于何时在何处是怎样修改的打开文件数?

加载中
1
k
kchr

正常的程序不会用运行 ulimit 命令的方式来改变环境。你看一下是不是用 setrlimit() 函数

http://man7.org/linux/man-pages/man2/setrlimit.2.html 加 RLIMIT_NOFILE 实现的

RLIMIT_NOFILE Specifies a value one greater than the maximum file descriptor
              number that can be opened by this process

可以用 strace 和 ltrace 察看进程和系统/库的交互行为。

zgw06629
zgw06629
你好 请问你可曾通过gdb调试过hotspot代码 能帮我看下这个问题吗 见http://www.oschina.net/question/1175066_237929
zgw06629
zgw06629
谢谢! 见下面的回复
0
zgw06629
zgw06629

在Openjdk目录中搜索setrlimit,

$ grep -r setrlimit
...
hotspot/src/os/linux/vm/os_linux.cpp:    // if getrlimit/setrlimit fails but continue regardless.
hotspot/src/os/linux/vm/os_linux.cpp:      status = setrlimit(RLIMIT_NOFILE, &nbr_files);
hotspot/src/os/linux/vm/os_linux.cpp:          perror("os::init_2 setrlimit failed");
...

$ vi hotspot/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");
      }
    }
  }
...

$ strace -f -o RuntimeTest.strace java RuntimeTest
$ vi RuntimeTest.strace
...
20766 getrlimit(RLIMIT_NOFILE, {rlim_cur=1024, rlim_max=4*1024}) = 0
20766 setrlimit(RLIMIT_NOFILE, {rlim_cur=4*1024, rlim_max=4*1024}) = 0
...



不知strace中的两个系统调用是否对应os_linux.cpp中的那段代码?

zgw06629
zgw06629
对! 用你说的办法确实证明了是在此处改变的打开文件数。 显式改为:nbr_files.rlim_cur = 2048; 然后重新编译hotspot, 输出结果为2048了。 若是修改为4567, 提示无效参数, 最后会是默认的1024.
k
kchr
不好意思,我不怎么用调试器的,gdb 就更不会了。
k
kchr
很简单啊,你可以改变源代码,强行指定 setrlimit 到比如一个足够大 的特殊数字比如 4567,看 strace 中出现 4567 就知道确实是这个 setrlimit 在起作用了。
返回顶部
顶部