Javaアプリケーション内からVM引数を取得する方法は?


162

JVMに渡すことができるオプションが明示的に設定されているか、デフォルト値があるかどうかを確認する必要があります。

具体的に言うと、デフォルトのスタックサイズよりも大きいネイティブスタックサイズの特定のスレッドを1つ作成する必要がありますが、ユーザーが-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
OracleのJVMでの実行が保証されていて、有用な引数を解析するコードがある場合。
laz

2
@VulcanそれはVM引数を取得しません。これには、メインクラス名と、メインメソッドへのargs配列が含まれます。
dacongy 2012

@dacongy VM引数がsun.java.commandシステムプロパティにあることを示唆したことはありません。プロパティを使用してメインクラス名を取得できると述べました(@lazが指摘したように、そのプロパティはOracleのJVMにのみ存在することは述べていません)。
FThompson 2012

206

起動時にこれを渡します -Dname=value

そしてあなたのコードではあなたが使うべきです

value=System.getProperty("name");

その値を取得する


4
これを使用して
-Xdebug

20
なぜこの回答が非常に賛成されているのかわからないため、これはアプリケーションパラメータ(-Dで指定)のみを取得し、VMパラメータ(-Xで指定)は取得しません。問題は特に-X paramsについてです。
cleberz 2017年

4
タイプのパラメーター-Dname=valueはJVM引数であり、-X引数に本質的な違いはないと信じていたので、ここに来ました。実際、これらは両方ともコマンドラインでアプリケーションではなくjavaに渡され-Drun.jvmArguments=...ます。例として証拠として、mavenでは両方としてとして渡すことができます。私はそれが賛成されている理由だと思います。
kap

これは、元のポスターのニーズにまったく応えません。
dan.mはuser2321368 2017

4
かもしれない!しかし、「コードでVMオプションを読み取る方法」を検索すると、トップにググって、それが関連する理由です)
62mkv

4

HotSpotが-clientと-serverを除いて、管理Bean内のすべての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>

最後の注意:コマンドライン引数内にスペースがあるというまれなケースを処理するために、これを拡張することもできます。


うん、やった。乾杯:)
ステファンライヒ

2

特にVM設定を取得することは試みていませんが、JMXユーティリティ、特にMXBeanユーティリティには豊富な情報があります。これが私が始めるところです。うまくいけば、あなたはそこにあなたを助ける何かを見つけます。

太陽のウェブサイトは技術に束を持っています:

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


0

Javaプロセスのコマンドライン全体が必要な場合 は、JvmArguments.javaを使用できます(ほとんどのUNIX実装をカバーするためにJNA + / procの組み合わせを使用します)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.