Java: Vollständige Liste der -XX:-Optionen

von Hubert Schmid vom 2013-10-20

Wie die meisten Programme gibt auch die Java-Virtual-Machine eine kurze Hilfe zu Kommandozeilenargumenten aus, wenn sie mit dem Argument -help aufgerufen wird. Darunter finden sich bei fast jeder Implementierung der Schalter -cp um anzugeben, wo nach Klassen gesucht wird, sowie der Schalter -D mit dem System-Properties gesetzt werden können.

$ java -help Usage: java [-options] class [args...] (to execute a class) or java [-options] -jar jarfile [args...] (to execute a jar file) where options include: -d32 use a 32-bit data model if available -d64 use a 64-bit data model if available -server to select the "server" VM ... [43 more lines]

Die Ausgabe weist auch darauf hin, dass mit -X Informationen zu weiteren Optionen ausgegeben werden. Dazu gehört insbesondere -Xmx für die maximale Größe des Java-Heaps. Dieser Konfigurationsparameter ist weithin bekannt, da seine Voreinstellung für die meisten Anwendungen unpassend ist.

$ java -X -Xmixed mixed mode execution (default) -Xint interpreted mode execution only -Xbootclasspath:<directories and zip/jar files separated by :> set search path for bootstrap classes and resources -Xbootclasspath/a:<directories and zip/jar files separated by :> append to end of bootstrap class path -Xbootclasspath/p:<directories and zip/jar files separated by :> prepend in front of bootstrap class path ... [26 more lines]

Die beiden Listen sind allerdings nicht vollständig. Es fehlen wichtige Schalter wie -XX:+UseCompressedOops, um den Speicherverbrauch auf Systemen mit weniger als 32 GiB zu optimieren, -XX:+PrintGCDetails für die Analyse des GC-Overheads und -XX:+TraceClassLoading, um Probleme mit mehrfach im Pfad vorhandenen Klassen aufzuspüren. Es gibt auch keinen Hinweis, wie man weitere Informationen bekommt – abgesehen von einem Verweis auf Oracles Online-Dokumentation, die allerdings nur ausgewählte Kommandozeilenargumente beschreibt.

Es ist kaum überraschend, dass die Java‑VM ihre möglichen Konfigurationsparameter kennt. Kaum bekannt ist hingegen, dass die meisten Hotspot-basierten Java‑VMs sich die Liste einschließlich der Defaultwerte einfach entlocken lassen. Dafür ist lediglich die Option -XX:+PrintFlagsFinal anzugeben. Über 600 Konfigurationsparameter spuckt die Version 1.7 des OpenJDK damit aus.

$ java -XX:+PrintFlagsFinal -version [Global flags] uintx AdaptivePermSizeWeight = 20 {product} uintx AdaptiveSizeDecrementScaleFactor = 4 {product} uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product} uintx AdaptiveSizePausePolicy = 0 {product} uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product} uintx AdaptiveSizePolicyInitializingSteps = 20 {product} uintx AdaptiveSizePolicyOutputInterval = 0 {product} ... [684 more lines]

Doch auch diese Liste ist noch nicht vollständig. Es gibt zwei weitere Schalter, um zusätzliche Features freizuschalten. Mit -XX:+UnlockDiagnosticVMOptions und -XX:+UnlockExperimentalVMOptions erhält man Zugang zu Konfigurationsparameters, die stärkeren Änderungen unterworfen sind. Die Liste vergrößert sich damit auf über 700:

$ java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version [Global flags] uintx AdaptivePermSizeWeight = 20 {product} uintx AdaptiveSizeDecrementScaleFactor = 4 {product} uintx AdaptiveSizeMajorGCDecayTimeScale = 10 {product} uintx AdaptiveSizePausePolicy = 0 {product} uintx AdaptiveSizePolicyCollectionCostMargin = 50 {product} uintx AdaptiveSizePolicyInitializingSteps = 20 {product} uintx AdaptiveSizePolicyOutputInterval = 0 {product} ... [785 more lines]

Und nun? Was soll man mit diesen über 700 Konfigurationsparametern anfangen?

Am Besten lässt man sie unverändert! Schließlich gibt es einen guten Grund, aus dem sie so verborgen sind: Ihre Wirkung auf große Anwendungen ist für Nutzer kaum vorauszusagen, und was für eine Methode vorteilhaft sein kann, kann sich an anderer Stelle als großer Nachteil erweisen.

Dennoch ist es gut zu wissen, wie man an die Liste herankommt. Denn manches Verhalten der Java‑VM lässt sich viel einfacher mit einem Blick in die Interna erklären. Beispielsweise bin ich vor Kurzem über die Frage gestolpert, warum sich ein Programm mit Arrays der Länge 64 ganz anders verhält als mit Arrays der Länge 65. Ein Blick in die Ausgabe von -XX:+PrintFlagsFinal förderte die Option -XX:EliminateAllocationArraySizeLimit=64 zu Tage, wodurch schnell klar wurde, dass Arrays mit bis zu 64 Elementen unter bestimmten Umständen wegoptimiert werden.

Also: Gucken erlaubt, Anfassen verboten!