2013-06-07 18 views
8

Kontekst: Przeprowadzam testy wydajności aplikacji Java, która jest uruchamiana przez kilka warstw pośrednich, tak, że nie jestem całkowicie pewien, czy aplikacja jest uruchamiana z flagami, które moim zdaniem są. Chciałbym mojego wniosku o włączenie do testow (przed rozpoczęciem jego testu wydajności) i zawierać w wynikach (po badaniu) informacje na temat JVM został dostrojony, takich jak:W ramach działającej maszyny JVM, jak programowo określić opcje jvm używane podczas uruchamiania?

  • Który był śmieci kolektor używany?
  • Czy/aktywnie robi profilowanie cpu?
  • Czy/jest rejestrowanie aktywności gc?
  • Czy był/jest w trybie -Xint lub -Xmixed?
  • Był/jest -XX:ParallelGCThreads zestaw - jeśli tak, do czego, a jeśli nie, jaki jest domyślny dla tej kompilacji?
  • Było/jest -XX:UseCompressedOops włączone lub wyłączone?
  • itp

Czy jest jakiś sposób na kod Java (JVM w uruchomionym) kwerendy rzeczywiste opcje używane do jego zawierającej JVM? (Załóżmy, że nie widzę linii poleceń, która uruchomiła mnie, więc nie mogę ponownie przeanalizować tych flag.)

Jeśli nie ma ogólnego sposobu, aby to ustalić, odpowiedzi, które są specyficzne dla pożądana jest również konkretna implementacja JVM.

UPDATE:

To ważne rozwiązanie, aby móc wiedzieć, jakie są wartości domyślne dla dowolnej wartości, które nie są wyraźnie dostarczane na linii poleceń. W przeciwnym razie, będzie wymagało to wiele (nużących błędów) prac, aby sprawdzić, jaka jest domyślna wartość danej kombinacji JVM/platforma/wersja/architektura. Testuję na różnych maszynach JVM, więc nie chcę ręcznie wymyślać, jakie jest domyślne ustawienie dla każdego parametru w każdym wydaniu jvm.

+0

Możesz wyświetlić proces JVM rozpoczęty przez PID za pomocą 'ps -ef' i tam możesz zobaczyć cały argument wejściowy tego procesu. To powinno działać dla dowolnego typu maszyny JVM. –

+0

@AlesJ. OP stwierdził, że podejście linii poleceń nie jest opcją –

+0

@AlesJ. - to dałoby mi tylko jawnie ustawione wartości, więc nie otrzymałbym żadnych informacji o domyślnych wartościach domyślnych maszyny JVM (patrz pytanie o aktualizację do pytania). :-( – Mickalot

Odpowiedz

2

Można używać klienta JMX (jak VisualVM), a następnie zadzwonić getVMOption(String name) patrz HotSpotDiagnosticMXBean.

Jeśli można przekazać co najmniej jeden zestaw flag do włączenia rejestrowania JVM, powinien on być --XX:+LogVMOutput -XX:LogFile=jvm.log, a następnie przeanalizować dane wyjściowe dziennika z aplikacji. Dziennik zawiera wszystkie flagi/parametry używane do uruchamiania JVM.

Inną opcją jest wymień proces JVM uruchomiony przez PID z ps -ef i tam możesz zobaczyć cały argument wejściowy tego procesu. To powinno działać dla dowolnego typu maszyny JVM.

+0

nie jest specyfikacją HotSpotDiagnosticMXBean Oracle JVM? –

+0

@OlegMichheev - Chociaż nie jest idealny, chciałbym zadowolić się rozwiązaniami specyficznymi dla JVM (większość użytkowników prawdopodobnie będzie na JVM Hotspot). Ale HotSpotDiagnosticMXBean wygląda tak samo jak niepoprawny komponent bean ... mówi mi, jakie diagnostyki są na miejscu (jak to, co powinien logować podczas wykonywania GC), a nie w jaki sposób VM jest dostrojona. – Mickalot

+0

@AlesJ. - Wypróbowałem kilka jdksów Sun/Oracle J2SE (głównie 1.6/1.7 32/64-bit na Linux) i żadne nie rozpoznaje -XX: + LogVMOutput. Tego też nie widzę tutaj: http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html. Którą maszynę JVM używasz, która ją akceptuje? – Mickalot

5

Można uzyskać argumenty wiersza poleceń przez

ManagementFactory.getRuntimeMXBean().getInputArguments(); 
+0

To była również moja pierwsza myśl, ale czy można jej użyć do określenia szczegółów, takich jak *, który został użyty do zbierania śmieci *, * czy aktywnie profiluje cpu *, i tak dalej? Uważam, że powinieneś rozwinąć w swojej odpowiedzi: – Vulcan

+0

Całkowicie to doceniam (i to była pierwsza rzecz, której próbowałem), ale powodem, dla którego nie jest to tym, czego szukam, jest to, że jeśli opcja JVM jest nieokreślona, ​​jest ustawiona na wartość domyślną JVM i nie jest to na tej liście (która zawiera tylko jawnie określone argumenty), więc nie odpowiada na pytanie "Jaki jest domyślny dla tej kompilacji?" Testuję na wielu różnych maszynach, z których każda może mieć nieco inna kompozycja z sligiem htly różne domyślne. – Mickalot

2

Poniższy kod Java 7 wyświetli wszystkie opcje JVM zwrócone przez -XX:+PrintFlagsFinal. Próbuje użyć odbicia, aby uzyskać dostęp do chronionej pakietem klasy pomocniczej Flag (dostępnej od wersji Java 6) i wraca do wersji HotSpotDiagnosticMXBean.getDiagnosticOptions(), jeśli to nie działa.

// load the diagnostic bean first to avoid UnsatisfiedLinkError 
final HotSpotDiagnosticMXBean hsdiag = ManagementFactory 
     .getPlatformMXBean(HotSpotDiagnosticMXBean.class); 
List<VMOption> options; 
try { 
    final Class<?> flagClass = Class.forName("sun.management.Flag"); 
    final Method getAllFlagsMethod = flagClass.getDeclaredMethod("getAllFlags"); 
    final Method getVMOptionMethod = flagClass.getDeclaredMethod("getVMOption"); 
    getAllFlagsMethod.setAccessible(true); 
    getVMOptionMethod.setAccessible(true); 
    final Object result = getAllFlagsMethod.invoke(null); 
    final List<?> flags = (List<?>) result; 
    options = new ArrayList<VMOption>(flags.size()); 
    for (final Object flag : flags) { 
     options.add((VMOption) getVMOptionMethod.invoke(flag)); 
    } 
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException 
     | InvocationTargetException | ClassCastException e) { 
    if (hsdiag != null) { 
     // only includes writable external flags 
     options = hsdiag.getDiagnosticOptions(); 
    } else { 
     options = Collections.emptyList(); 
    } 
} 
final Map<String, VMOption> optionMap = new TreeMap<>(); 
for (final VMOption option : options) { 
    optionMap.put(option.getName(), option); 
} 
for (final VMOption option : optionMap.values()) { 
    System.out.println(option.getName() + " = " + option.getValue() + " (" + 
      option.getOrigin() + ", " + 
      (option.isWriteable() ? "read-write" : "read-only") + ")"); 
} 
System.out.println(options.size() + " options found"); 

Z 7u71, otrzymuję 663 opcji, lub -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions, 779.