如何从 Java 应用程序内部获取 VM 参数?

我需要检查一些可以传递给 JVM 的选项是显式设置的还是具有默认值。

更具体地说: 我需要创建一个本地堆栈大小高于默认大小的特定线程,但是如果用户想通过指定 -Xss选项自己处理这些事情,我想创建所有具有默认堆栈大小的线程(将由用户 in-Xss 选项指定)。

我已经检查过像 java.lang.Systemjava.lang.Runtime这样的类,但是它们没有提供任何关于 VM 参数的有用信息。

有什么办法能得到我需要的信息吗?

195729 次浏览

我没有尝试特别获取 VM 设置,但是在 JMX 实用程序中有大量的信息,特别是 MXBean 实用程序。我会从这里开始。希望你能找到能帮助你的东西。

Sun 网站上有很多关于这项技术的文章:

Http://java.sun.com/javase/6/docs/technotes/guides/management/mxbeans.html

通过这段代码,您可以得到 JVM 参数:

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
...
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();

在启动时通过这个 -Dname=value

然后在代码中使用

value=System.getProperty("name");

才能得到那个价值

如果需要 Java 进程的整个命令行,可以使用: < a href = “ https://github.com/zolyfarkas/spf4j/blob/master/spf4j-core/src/main/java/org/spf4j/unix/JVMArguments.java”rel = “ nofollow noReferrer”> JvmArguments.java (使用 JNA +/proc 的组合来覆盖大多数 unix 实现)

我发现 HotSpot 列出了管理 bean 中除-client 和-server 之外的所有 VM 参数。因此,如果从 VM 名称推断出-client/-server 参数,并将其添加到运行时管理 bean 的列表中,就会得到完整的参数列表。

这是 SSCCE:

import java.util.*;
import java.lang.management.ManagementFactory;


class main {
public static void main(final String[] args) {
System.out.println(fullVMArguments());
}


static String fullVMArguments() {
String name = javaVmName();
return (contains(name, "Server") ? "-server "
: contains(name, "Client") ? "-client " : "")
+ joinWithSpace(vmArguments());
}


static List<String> vmArguments() {
return ManagementFactory.getRuntimeMXBean().getInputArguments();
}


static boolean contains(String s, String b) {
return s != null && s.indexOf(b) >= 0;
}


static String javaVmName() {
return System.getProperty("java.vm.name");
}


static String joinWithSpace(Collection<String> c) {
return join(" ", c);
}


public static String join(String glue, Iterable<String> strings) {
if (strings == null) return "";
StringBuilder buf = new StringBuilder();
Iterator<String> i = strings.iterator();
if (i.hasNext()) {
buf.append(i.next());
while (i.hasNext())
buf.append(glue).append(i.next());
}
return buf.toString();
}
}

如果你想要 List<String>中的参数,可以缩短。

最后注意: 我们可能还想扩展这个函数来处理命令行参数中有空格的罕见情况。