如何从java应用程序内部获取vm参数?

oku*_*ane 152 java jvm jvm-arguments

我需要检查是否可以传递给JVM的某个选项是显式设置还是具有默认值.

更具体一点:
我需要创建一个具有比默认堆栈大更高的本机堆栈大小的特定线程,但是如果用户希望通过指定-Xss选项来自己处理这些事情,我想创建具有默认堆栈大小的所有线程(这将由用户在-Xss选项中指定).

我检查类,如java.lang.Systemjava.lang.Runtime,但这些都没有给我有关的信息-Xss.

有没有办法获得我需要的信息?

小智 189

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

然后在你的代码中你应该使用

value=System.getProperty("name");
Run Code Online (Sandbox Code Playgroud)

获得这个价值

  • 不确定为什么这个答案如此受欢迎,这只会检索应用程序参数(使用-D指定),而不是VM参数(使用-X指定的参数).问题特别是关于-X params. (14认同)
  • 我不能用它来获得-Xdebug (4认同)
  • 我来到这里是因为我认为`-Dname = value`类型的参数是JVM参数,并且`-X`参数没有内在差异.实际上,它们都被传递给java而不是命令行中的应用程序,并且作为示例的证据,在maven中你可以将它们作为`-Drun.jvmArguments = ...`传递.我相信这就是它被投票的原因. (4认同)
  • 可能 !但是在搜索“如何读取代码中的VM选项”时,它会排在首位,这就是为什么它是相关的) (3认同)
  • 这根本不能满足原始海报的需求。 (2认同)

Dav*_*ler 174

使用此代码,您可以获取JVM参数:

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
...
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
Run Code Online (Sandbox Code Playgroud)

  • @laz System.getProperty("sun.java.command")简单得多. (7认同)
  • 如果您保证在Oracle的JVM上运行并拥有解析可能有用的参数的代码. (3认同)
  • @Vulcan这不会得到VM参数.它包含主类名,以及main方法的args数组. (2认同)

Ste*_*ich 6

我发现 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();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您想要List<String>.

最后一点:我们可能还想扩展它以处理在命令行参数中包含空格的罕见情况。