Mic*_*lot 9 java jvm jvm-arguments
背景:我正在对通过多层间接启动的Java应用程序进行一些性能测试,这样我就不能完全确定应用程序是否会使用我认为的标志启动.我希望我的应用程序包括一个健全性检查(在它开始性能测试之前)并在结果中(在测试之后)包含有关如何调整JVM的信息,例如:
-Xint
还是-Xmixed
模式?-XX:ParallelGCThreads
设置 - 如果是,如果是,如果没有,这个构建的默认值是什么?-XX:UseCompressedOops
开启或关闭?有没有办法让Java代码(在正在运行的JVM中)查询用于包含JVM的实际选项?(假设我看不到启动我的命令行,所以我无法重新解析那些标志.)
如果没有通用的方法来确定这一点,那么也欢迎特定于特定JVM实现的答案.
更新:
对于解决方案而言,重要的是能够知道命令行中未明确提供的任何值的默认值.否则,它将涉及很多(容易出错的)腿部工作,以查找给定组合JVM /平台/版本/体系结构的默认值.我正在测试各种各样的JVM,所以我不想手动找出每个jvm版本中每个参数的默认设置.
您可以通过获取命令行参数
ManagementFactory.getRuntimeMXBean().getInputArguments();
Run Code Online (Sandbox Code Playgroud)
以下 Java 7 代码将列出 . 返回的所有 JVM 选项-XX:+PrintFlagsFinal
。它尝试使用反射来访问受包保护的帮助器类(自 Java 6 起可用),如果不起作用,则Flag
回退到该类。HotSpotDiagnosticMXBean.getDiagnosticOptions()
// load the diagnostic bean first to avoid UnsatisfiedLinkError
final HotSpotDiagnosticMXBean hsdiag = ManagementFactory
.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
List<VMOption> options;
try {
final Class<?> flagClass = Class.forName("sun.management.Flag");
final Method getAllFlagsMethod = flagClass.getDeclaredMethod("getAllFlags");
final Method getVMOptionMethod = flagClass.getDeclaredMethod("getVMOption");
getAllFlagsMethod.setAccessible(true);
getVMOptionMethod.setAccessible(true);
final Object result = getAllFlagsMethod.invoke(null);
final List<?> flags = (List<?>) result;
options = new ArrayList<VMOption>(flags.size());
for (final Object flag : flags) {
options.add((VMOption) getVMOptionMethod.invoke(flag));
}
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException | ClassCastException e) {
if (hsdiag != null) {
// only includes writable external flags
options = hsdiag.getDiagnosticOptions();
} else {
options = Collections.emptyList();
}
}
final Map<String, VMOption> optionMap = new TreeMap<>();
for (final VMOption option : options) {
optionMap.put(option.getName(), option);
}
for (final VMOption option : optionMap.values()) {
System.out.println(option.getName() + " = " + option.getValue() + " (" +
option.getOrigin() + ", " +
(option.isWriteable() ? "read-write" : "read-only") + ")");
}
System.out.println(options.size() + " options found");
Run Code Online (Sandbox Code Playgroud)
使用 7u71,我有 663 个选项,或者使用-XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
779。
您可以使用 JMX 客户端(如 VisualVM),然后调用getVMOption(String name)
,请参阅HotSpotDiagnosticMXBean。
或者,如果您可以传入至少一组标志来启用 JVM 日志记录,那么应该--XX:+LogVMOutput -XX:LogFile=jvm.log
然后解析应用程序的日志输出。该日志包含用于启动 JVM 的所有标志/参数。
另一种选择是列出由 PID 启动的JVM 进程ps -ef
,您可以在其中看到该进程的所有输入参数。这应该适用于任何 JVM 类型。