Exploration des indicateurs de réglage JVM

1. Vue d'ensemble

Il est possible de régler la JVM HotSpot avec une variété d'indicateurs de réglage. Comme il existe des centaines de ces indicateurs, les suivre et leurs valeurs par défaut peut être un peu intimidant.

Dans ce didacticiel, nous allons présenter quelques façons de découvrir de tels indicateurs de réglage et d'apprendre à les utiliser.

2. Présentation des options Java

La commande java prend en charge une grande variété d'indicateurs appartenant aux catégories suivantes:

  • Options standard qui sont assurées d'être prises en charge par toutes les implémentations JVM. Habituellement, ces options sont utilisées pour des actions quotidiennes telles que –classpath, -cp, –version, etc.
  • Options supplémentaires qui ne sont pas prises en charge par toutes les implémentations JVM et sont généralement sujettes à modification. Ces options commencent par -X

Veuillez noter que nous ne devons pas utiliser ces options supplémentaires avec désinvolture. De plus, certaines de ces options supplémentaires sont plus avancées et commencent par -XX .

Tout au long de cet article, nous allons nous concentrer sur les indicateurs -XX plus avancés .

3. Drapeaux de réglage JVM

Pour répertorier les indicateurs de réglage JVM globaux, nous pouvons activer l' indicateur PrintFlagsFinal comme suit:

>> java -XX:+PrintFlagsFinal -version [Global flags] uintx CodeCacheExpansionSize = 65536 {pd product} {default} bool CompactStrings = true {pd product} {default} bool DoEscapeAnalysis = true {C2 product} {default} double G1ConcMarkStepDurationMillis = 10.000000 {product} {default} size_t G1HeapRegionSize = 1048576 {product} {ergonomic} uintx MaxHeapFreeRatio = 70 {manageable} {default} // truncated openjdk version "14" 2020-03-17 OpenJDK Runtime Environment (build 14+36-1461) OpenJDK 64-Bit Server VM (build 14+36-1461, mixed mode, sharing)

Comme indiqué ci-dessus, certains indicateurs ont des valeurs par défaut pour cette version JVM particulière.

Les valeurs par défaut de certains indicateurs peuvent être différentes sur différentes plates-formes, ce qui est indiqué dans la dernière colonne. Par exemple, le produit signifie que le paramètre par défaut du drapeau est uniforme sur toutes les plates-formes; le produit pd signifie que le paramètre par défaut de l'indicateur dépend de la plate-forme. Les valeurs gérables peuvent être modifiées dynamiquement lors de l'exécution.

3.1. Drapeaux de diagnostic

L' indicateur PrintFlagsFinal , cependant, n'affiche pas tous les indicateurs de réglage possibles. Par exemple, pour voir également les indicateurs de réglage de diagnostic, nous devons ajouter l' indicateur UnlockDiagnosticVMOptions :

>> java -XX:+PrintFlagsFinal -version | wc -l 557 >> java -XX:+PrintFlagsFinal -XX:+UnlockDiagnosticVMOptions -version | wc -l 728

De toute évidence, il y a quelques centaines d'indicateurs supplémentaires lorsque nous incluons des options de diagnostic. Par exemple, l'impression des statistiques de suivi de la mémoire native n'est disponible que dans le cadre des indicateurs de diagnostic:

bool PrintNMTStatistics = false {diagnostic} {default}

3.2. Drapeaux expérimentaux

Pour voir également les options expérimentales, nous devons ajouter l' indicateur UnlockExperimentalVMOptions :

>> java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version | wc -l 809

3.3. Drapeaux JVMCI

A partir de Java 9, l'interface du compilateur JVM ou JVMCI nous permet d'utiliser un compilateur écrit en Java, tel que Graal, comme compilateur dynamique.

Pour voir les options liées à JVMCI, nous devrions ajouter quelques indicateurs supplémentaires et même activer le JVMCI:

>> java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions \ >> -XX:+JVMCIPrintProperties -XX:+EnableJVMCI -XX:+PrintFlagsFinal -version | wc -l 1516

La plupart du temps, cependant, l'utilisation d'options globales, diagnostiques et expérimentales devrait suffire et nous aidera à trouver le drapeau que nous avons en tête.

3.4. Mettre tous ensemble

Ces combinaisons d'options peuvent nous aider à trouver un indicateur de réglage, surtout lorsque nous ne nous souvenons pas du nom exact. Par exemple, pour trouver l'indicateur de réglage lié aux références logicielles en Java:

>> alias jflags="java -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions -XX:+PrintFlagsFinal -version" >> jflags | grep Soft size_t SoftMaxHeapSize = 4294967296 {manageable} {ergonomic} intx SoftRefLRUPolicyMSPerMB = 1000 {product} {default}

D'après le résultat, nous pouvons facilement deviner que SoftRefLRUPolicyMSPerMB est le drapeau que nous recherchons.

4. Différents types de drapeaux

Dans la section précédente, nous avons passé sous silence un sujet important: les types de drapeaux. Jetons un autre coup d'œil à la sortie java -XX: + PrintFlagsFinal -version :

[Global flags] uintx CodeCacheExpansionSize = 65536 {pd product} {default} bool CompactStrings = true {pd product} {default} bool DoEscapeAnalysis = true {C2 product} {default} double G1ConcMarkStepDurationMillis = 10.000000 {product} {default} size_t G1HeapRegionSize = 1048576 {product} {ergonomic} uintx MaxHeapFreeRatio = 70 {manageable} {default} // truncated

Comme indiqué ci-dessus, chaque drapeau a un type spécifique.

Les options booléennes sont utilisées pour activer ou désactiver une fonction . Ces options ne nécessitent pas de valeur. Pour les activer, il suffit de mettre un signe plus avant le nom de l'option:

-XX:+PrintFlagsFinal

Au contraire, pour les désactiver, il faut ajouter un signe moins avant leur nom:

-XX:-RestrictContended

Les autres types d'indicateur ont besoin d'une valeur d'argument. Il est possible de séparer la valeur du nom de l'option par un espace, un deux-points, un signe égal ou l'argument peut suivre directement le nom de l'option (la syntaxe exacte diffère pour chaque option):

-XX:ObjectAlignmentInBytes=16 -Xms5g -Xlog:gc

5. Documentation et code source

Trouver le bon nom de drapeau est une chose. Trouver ce que fait ce drapeau sous le capot est une autre histoire.

Une façon de trouver ce genre de détails est de consulter la documentation. Par exemple, la documentation de la commande java dans la section de spécification des outils JDK est un excellent point de départ.

Parfois, aucune documentation ne peut battre le code source. Par conséquent, si nous avons le nom d'un indicateur particulier, nous pouvons explorer le code source JVM pour découvrir ce qui se passe.

Par exemple, nous pouvons consulter le code source de HotSpot JVM depuis GitHub ou même leur référentiel Mercurial, puis:

>> git clone [email protected]:openjdk/jdk14u.git openjdk >> cd openjdk/src/hotspot >> grep -FR 'PrintFlagsFinal' . ./share/runtime/globals.hpp: product(bool, PrintFlagsFinal, false, ./share/runtime/init.cpp: if (PrintFlagsFinal || PrintFlagsRanges) {

Ici, nous recherchons tous les fichiers contenant la chaîne PrintFlagsFinal . Après avoir trouvé les fichiers responsables, nous pouvons regarder autour de vous et voir comment ce drapeau spécifique fonctionne.

6. Conclusion

Dans cet article, nous avons vu comment nous pouvions trouver presque tous les indicateurs de réglage JVM disponibles et avons également appris quelques astuces pour travailler avec eux plus efficacement.