วิธีรับอาร์กิวเมนต์ 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 และมีรหัสเพื่อแยกอาร์กิวเมนต์ที่มีประโยชน์
laz

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 params โดยเฉพาะ
cleberz

5
ฉันมาที่นี่เพราะฉันเชื่อว่าพารามิเตอร์ประเภท-Dname=valueเป็นอาร์กิวเมนต์ JVM และไม่มีความแตกต่างที่แท้จริงในการ-Xขัดแย้ง ที่จริงพวกเขามีทั้งที่ส่งผ่านไปยัง Java และไม่ได้เป็นโปรแกรมที่บรรทัดคำสั่งและเป็นหลักฐานโดยตัวอย่างใน Maven -Drun.jvmArguments=...คุณสามารถส่งผ่านทั้งสองเป็น ฉันเชื่อว่าเป็นเหตุผลที่ upvoted
kap

นี่ไม่ได้ตอบความต้องการของผู้โพสต์ดั้งเดิมเลย
dan.m คือผู้ใช้ 2321368

4
อาจจะ ! แต่มันเป็น googles บนยอดเมื่อค้นหา "วิธีการอ่านตัวเลือก VM ในรหัส" และนั่นคือเหตุผลที่มันเกี่ยวข้อง)
62mkv

4

ฉันพบว่า HotSpot แสดงรายการอาร์กิวเมนต์ VM ทั้งหมดใน Management bean ยกเว้น -client และ -server ดังนั้นหากคุณอนุมานอาร์กิวเมนต์ -client / -server จากชื่อ VM และเพิ่มสิ่งนี้ในรายการของ bean Management runtime คุณจะได้รับรายการอาร์กิวเมนต์ทั้งหมด

นี่คือ 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>อาจจะทำให้สั้นลงถ้าคุณต้องการข้อโต้แย้งในส่วน

หมายเหตุสุดท้าย: เราอาจต้องการขยายสิ่งนี้เพื่อจัดการกับกรณีที่ไม่ค่อยเกิดขึ้นของการมีช่องว่างภายในอาร์กิวเมนต์บรรทัดคำสั่ง


ใช่เพิ่งทำ ไชโย :)
Stefan Reich

2

ฉันไม่ได้ลองรับการตั้งค่า VM โดยเฉพาะ แต่มีข้อมูลจำนวนมากในโปรแกรมอรรถประโยชน์ JMX โดยเฉพาะอย่างยิ่งยูทิลิตี้ MXBean นี่จะเป็นจุดเริ่มต้นของฉัน หวังว่าคุณจะพบบางสิ่งที่นั่นเพื่อช่วยเหลือคุณ

เว็บไซต์ของดวงอาทิตย์มีเทคโนโลยีมากมาย:

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


0

หากคุณต้องการบรรทัดคำสั่งทั้งหมดของกระบวนการ Java ของคุณคุณสามารถใช้: JvmArguments.java (ใช้การรวมกันของ JNA + / proc เพื่อให้ครอบคลุมการใช้งานยูนิกซ์ส่วนใหญ่)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.