Как получить аргументы VM изнутри Java-приложения?


162

Мне нужно проверить, явно ли установлена ​​какая-либо опция, которая может быть передана в JVM, или имеет значение по умолчанию.

Чтобы быть более конкретным: мне нужно создать один конкретный поток с более высоким собственным размером стека, чем по умолчанию, но в случае, если пользователь хочет сам позаботиться о таких вещах, указав -Xssопцию, я хочу создать все потоки с размером стека по умолчанию (который будет указан пользователем в опции -Xss).

Я проверил классы как java.lang.Systemи java.lang.Runtime, но они не дают мне никакой полезной информации об аргументах VM.

Есть ли способ получить нужную мне информацию?

Ответы:


183

С помощью этого кода вы можете получить аргументы JVM:

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

К сожалению, вы не можете получить имя основного класса, если оно указано в командной строке.
Даниэль

@ Даниил, это должно дать вам имя основного класса: final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final String mainClassName = stackTrace[stackTrace.length - 1].getClassName());
Лаз

3
Если вы гарантированно работаете на Oracle JVM и имеете код для анализа аргументов, которые могут быть полезны.
Лаз

2
@Vulcan Это не получает аргументы VM. Он содержит имя основного класса и массив args основного метода.
2012 года

@dacongy Никогда я не подразумевал, что аргументы ВМ находятся в sun.java.commandсистемном свойстве; Я сказал, что свойство можно использовать для получения имени основного класса (хотя я и не упомянул, как отметил @laz, это свойство присутствует только в JVM Oracle).
FThompson

207

При запуске пройти этот -Dname=value

а затем в вашем коде вы должны использовать

value=System.getProperty("name");

чтобы получить это значение


4
Я не могу использовать это, чтобы получить -Xdebug
petertc

20
Не уверен, почему этот ответ был так отклонен, он получает только параметры приложения (указанные с -D), а не параметры виртуальной машины (те, которые указаны с -X). Вопрос конкретно о -X params.
Cleberz

5
Я пришел сюда, потому что полагал, что параметры типа -Dname=valueявляются аргументами JVM и что между аргументами нет принципиальной разницы -X. На самом деле, они оба передаются в java, а не в приложение из командной строки, и в качестве примера, в maven, вы можете передать оба как -Drun.jvmArguments=.... Я верю, что именно поэтому за это проголосовали.
кап

Это не отвечает оригинальным потребностям постеров вообще.
dan.m был user2321368

4
Возможно ! но он гуглится на вершинах при поиске «как читать опции виртуальной машины в коде», и именно поэтому это актуально)
62mkv

4

Я обнаружил, что HotSpot перечисляет все аргументы VM в bean-компоненте управления, кроме -client и -server. Таким образом, если вы выводите аргумент -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>.

Последнее замечание: мы могли бы также расширить это, чтобы обработать редкий случай наличия пробелов в аргументах командной строки.


Да, только что сделал. Приветствия :)
Стефан Райх

2

Я не пытался получить конкретные настройки ВМ, но в утилитах JMX, особенно в утилитах MXBean, содержится много информации. Это было бы то, где я бы начал. Надеюсь, вы найдете что-то там, чтобы помочь вам.

На сайте Sun есть куча технологий:

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


0

Если вам нужна вся командная строка вашего Java-процесса, вы можете использовать: JvmArguments.java (использует комбинацию JNA + / proc для охвата большинства реализаций Unix)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.