Bagaimana cara mendapatkan argumen VM dari dalam aplikasi Java?


162

Saya perlu memeriksa apakah beberapa opsi yang dapat diteruskan ke JVM secara eksplisit diatur atau memiliki nilai default.

Untuk lebih spesifik: Saya perlu membuat satu utas khusus dengan ukuran tumpukan asli lebih tinggi daripada yang standar, tetapi jika pengguna ingin mengurus hal-hal seperti itu sendiri dengan menentukan -Xssopsi saya ingin membuat semua utas dengan ukuran tumpukan default (yang akan ditentukan oleh pengguna dalam opsi -Xss).

Saya sudah memeriksa kelas suka java.lang.Systemdan java.lang.Runtime, tetapi ini tidak memberi saya informasi yang berguna tentang argumen VM.

Apakah ada cara untuk mendapatkan informasi yang saya butuhkan?

Jawaban:


183

Dengan kode ini Anda bisa mendapatkan argumen JVM:

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

Sayangnya Anda tidak bisa mendapatkan Nama kelas utama jika diberikan pada baris perintah.
Daniel

@Aniel, ini akan memberi Anda nama kelas utama: final StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); final String mainClassName = stackTrace[stackTrace.length - 1].getClassName());
laz

3
Jika Anda dijamin menjalankan pada JVM Oracle dan memiliki kode untuk menguraikan argumen yang dapat bermanfaat.
laz

2
@ Vulcan Itu tidak mendapatkan argumen VM. Ini berisi nama kelas utama, dan array args ke metode utama.
dacongy

@ Dacongy Tidak pernah saya menyiratkan bahwa argumen VM terletak di sun.java.commandproperti sistem; Saya mengatakan bahwa properti dapat digunakan untuk memperoleh nama kelas utama (meskipun saya tidak menyebutkan, seperti yang ditunjukkan @laz, bahwa properti hanya ada pada JVM Oracle).
FThompson

206

Saat startup, lewati ini -Dname=value

dan kemudian dalam kode Anda, Anda harus menggunakan

value=System.getProperty("name");

untuk mendapatkan nilai itu


4
Saya tidak bisa menggunakan ini untuk mendapatkan -Xdebug
petertc

20
Tidak yakin mengapa jawaban ini telah begitu dipilih, ini hanya mengambil parameter aplikasi (ditentukan dengan -D), bukan parameter VM (yang ditentukan dengan -X). Pertanyaannya secara khusus tentang -X params.
cleberz

4
Saya datang ke sini karena saya percaya parameter tipe -Dname=valueadalah argumen JVM dan tidak ada perbedaan intrinsik dengan -Xargumen. Sebenarnya, keduanya dilewatkan ke java dan bukan aplikasi di baris perintah dan sebagai bukti dengan contoh, di maven Anda dapat melewati keduanya -Drun.jvmArguments=.... Saya percaya itu adalah alasan mengapa hal itu dibatalkan.
kap

Ini tidak menjawab kebutuhan poster asli sama sekali.
dan.m adalah user2321368

4
Mungkin ! tetapi googles di atas ketika mencari "cara membaca opsi VM dalam kode" dan itulah mengapa itu relevan)
62mkv

4

Saya menemukan bahwa HotSpot mencantumkan semua argumen VM di kacang manajemen kecuali untuk -client dan -server. Jadi, jika Anda menyimpulkan argumen -client / -server dari nama VM dan menambahkan ini ke daftar kacang manajemen runtime, Anda mendapatkan daftar lengkap argumen.

Inilah 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();
  }
}

Dapat dibuat lebih pendek jika Anda ingin argumen dalam List<String>.

Catatan akhir: Kami mungkin juga ingin memperluas ini untuk menangani kasus langka memiliki spasi dalam argumen baris perintah.


Yup, baru saja melakukannya. Cheers :)
Stefan Reich


0

Jika Anda ingin seluruh baris perintah dari proses java Anda, Anda dapat menggunakan: JvmArguments.java (menggunakan kombinasi JNA + / proc untuk mencakup sebagian besar implementasi unix)

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.