Як отримати аргументи 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();

На жаль, ви не можете отримати ім'я основного класу, якщо воно вказане в командному рядку.
Даніель

@Daniel, це повинно отримати вам ім'я головного класу: final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final String mainClassName = stackTrace[stackTrace.length - 1].getClassName());
laz

3
Якщо ви гарантовано працюєте на JVM Oracle і у вас є код для розбору аргументів, які можуть бути корисними.
лаз

2
@Vulcan Це не отримує аргументів VM. Він містить ім'я основного класу та масив args до основного методу.
dacongy

@dacongy Ніколи не мав на увазі, що аргументи VM розташовані у sun.java.commandвластивості системи; Я сказав, що властивість можна використовувати для придбання основного імені класу (хоча я не згадував, як @laz вказував, що ця властивість присутня лише у JVM Oracle).
FThompson

207

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

а потім у своєму коді ви повинні використовувати

value=System.getProperty("name");

щоб отримати це значення


4
Я не можу використовувати це, щоб отримати -Xdebug
petertc

20
Не впевнений, чому ця відповідь настільки обґрунтована, це вилучає лише параметри програми (вказані з -D), а не параметри VM (ті, що вказані з -X). Питання стосується конкретно парам -X.
cleberz

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

Це взагалі не відповідає оригінальним потребам плакатів.
dan.m був користувач2321368

4
Може бути ! але він googles на вершинах під час пошуку "як читати параметри VM у коді", і тому це актуально)
62mkv

4

Я виявив, що HotSpot перераховує всі аргументи VM в біні управління, за винятком -client та -server. Таким чином, якщо вивідати аргумент -client / -server з імені VM та додати це до списку 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();
  }
}

Можна скоротити, якщо ви хочете, щоб аргументи в a List<String>.

Підсумкове зауваження: ми також можемо захотіти розширити це, щоб обробити рідкісний випадок пробілів в аргументах командного рядка.


Так, щойно. Ура :)
Стефан Рейх

2

Я не пробував спеціально отримувати налаштування VM, але є багато інформації в утилітах 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.