Java 응용 프로그램 내부에서 VM 인수를 얻는 방법은 무엇입니까?


162

JVM에 전달할 수있는 옵션이 명시 적으로 설정되어 있는지 또는 기본값이 있는지 확인해야합니다.

더 구체적으로 말하면 : 기본 스레드보다 기본 스택 크기가 더 높은 하나의 특정 스레드를 만들어야하지만 사용자가 -Xss옵션 을 지정하여 직접 처리 하려는 경우 기본 스택 크기의 모든 스레드를 만들고 싶습니다. (-Xss 옵션에서 사용자가 지정 함).

java.lang.Systemand과 같은 클래스를 확인 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());
알려줄 것입니다

3
Oracle의 JVM에서 실행되고 있고 유용한 인수를 구문 분석하는 코드가있는 경우.
laz

2
@Vulcan VM 인수를받지 않습니다. 기본 클래스 이름과 기본 메소드에 대한 args 배열을 포함합니다.
dacongy

@dacongy VM 인수가 sun.java.command시스템 속성 에 있다는 것을 결코 암시하지 않았습니다 . @laz가 지적했듯이 그 속성은 Oracle의 JVM에만 존재한다고 언급하지는 않았지만 속성은 기본 클래스 이름을 얻는 데 사용될 수 있다고 말했습니다.
FThompson

207

시작시 이것을 통과 -Dname=value

그런 다음 코드에서 사용해야합니다

value=System.getProperty("name");

그 가치를 얻기 위해


4
나는 GET -Xdebug이 사용할 수 없습니다
petertc

20
이 답변이 왜 그렇게 많이 찬성되었는지 확실하지 않으면 VM 매개 변수 (-X로 지정된 것)가 아닌 응용 프로그램 매개 변수 (-D로 지정됨) 만 검색합니다. 문제는 구체적으로 -X 매개 변수에 관한 것입니다.
cleberz

5
나는 유형의 매개 변수 -Dname=value가 JVM 인수 라고 믿고 인수와 본질적인 차이점이 없기 때문에 여기에 왔습니다 -X. 실제로, 그들은 명령 줄에서 응용 프로그램이 아닌 java로 전달되며 예제로 증거로 maven에서 모두를 전달할 수 있습니다 -Drun.jvmArguments=.... 나는 그것이 upvoted 이유입니다 생각합니다.
kap

이것은 원래의 포스터 요구에 전혀 응답하지 않습니다.
dan.m was user2321368

4
아마도 ! 그러나 "코드에서 VM 옵션을 읽는 방법"을 검색 할 때
Google에서 정상에 올라서므로 이것이

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>.

마지막 참고 사항 : 명령 줄 인수 내에 공백이있는 드문 경우를 처리하기 위해이를 확장 할 수도 있습니다.


응, 방금 했어 건배 :)
Stefan Reich


0

Java 프로세스의 전체 명령 행을 원하는 경우 다음을 사용할 수 있습니다. JvmArguments.java (JNA + / proc의 조합을 사용하여 대부분의 유닉스 구현을 포괄)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.