Guide des paramètres JVM les plus importants

1. Vue d'ensemble

Dans ce rapide didacticiel, nous explorerons les options les plus connues pouvant être utilisées pour configurer la machine virtuelle Java.

2. Mémoire de tas explicite - Options Xms et Xmx

L'une des pratiques les plus courantes liées aux performances consiste à initialiser la mémoire du tas conformément aux exigences de l'application.

C'est pourquoi nous devons spécifier la taille minimale et maximale du tas. Les paramètres ci-dessous peuvent être utilisés pour y parvenir:

-Xms[unit] -Xmx[unit]

Ici, unité désigne l'unité dans laquelle la mémoire (indiquée par la taille du tas ) doit être initialisée. Les unités peuvent être marquées «g» pour Go, «m» pour Mo et «k» pour Ko.

Par exemple, si nous voulons attribuer un minimum de 2 Go et un maximum de 5 Go à JVM, nous devons écrire:

-Xms2G -Xmx5G

À partir de Java 8, la taille de Metaspace n'est pas définie. Une fois qu'il atteint la limite globale, JVM l'augmente automatiquement, cependant, pour surmonter toute instabilité inutile, nous pouvons définir la taille de Metaspace avec:

-XX:MaxMetaspaceSize=[unit]

Ici, la taille de métaspace indique la quantité de mémoire que nous voulons attribuer à Metaspace .

Selon les directives d'Oracle, après la mémoire totale disponible, le deuxième facteur le plus influent est la proportion du tas réservée à la jeune génération. Par défaut, la taille minimale du YG est de 1310 Mo et la taille maximale est illimitée .

Nous pouvons les attribuer explicitement:

-XX:NewSize=[unit] -XX:MaxNewSize=[unit]

3. Collecte des ordures

Pour une meilleure stabilité de l'application, il est essentiel de choisir le bon algorithme de nettoyage de la mémoire.

JVM a quatre types d' implémentations GC :

  • Collecteur de déchets série
  • Collecteur d'ordures parallèle
  • Collecteur de déchets CMS
  • Garbage Collector G1

Ces implémentations peuvent être déclarées avec les paramètres ci-dessous:

-XX:+UseSerialGC -XX:+UseParallelGC -XX:+USeParNewGC -XX:+UseG1GC

Plus de détails sur les implémentations de Garbage Collection peuvent être trouvés ici.

4. Journalisation GC

Pour surveiller strictement la santé de l'application, nous devons toujours vérifier les performances de Garbage Collection de la JVM . Le moyen le plus simple de le faire est de consigner l' activité du GC dans un format lisible par l'homme.

En utilisant les paramètres suivants, nous pouvons enregistrer l' activité du GC :

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles= -XX:GCLogFileSize=[ unit ] -Xloggc:/path/to/gc.log

UseGCLogFileRotation spécifie la politique de roulement du fichier journal, tout comme log4j, s4lj, etc. NumberOfGCLogFiles indique le nombre maximal de fichiers journaux qui peuvent être écrits pour un cycle de vie d'application unique. GCLogFileSize spécifie la taille maximale du fichier. Enfin, loggc indique son emplacement.

Il convient de noter ici que deux paramètres JVM supplémentaires sont disponibles ( -XX: + PrintGCTimeStamps et -XX: + PrintGCDateStamps ) qui peuvent être utilisés pour imprimer l'horodatage par date dans le journal GC .

Par exemple, si nous voulons attribuer un maximum de 100 fichiers journaux GC , chacun ayant une taille maximale de 50 Mo et que nous voulons les stocker dans l' emplacement ' / home / user / log /' , nous pouvons utiliser la syntaxe ci-dessous:

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=50M -Xloggc:/home/user/log/gc.log

Cependant, le problème est qu'un thread démon supplémentaire est toujours utilisé pour surveiller l'heure du système en arrière-plan. Ce comportement peut créer un goulot d'étranglement des performances; c'est pourquoi il vaut toujours mieux ne pas jouer avec ce paramètre en production.

5. Manipulation de la mémoire

Il est très courant qu'une grande application soit confrontée à une erreur de mémoire insuffisante qui, à son tour, entraîne le blocage de l'application. C'est un scénario très critique et très difficile à reproduire pour résoudre le problème.

C'est pourquoi JVM est livré avec certains paramètres qui vident la mémoire du tas dans un fichier physique qui peut être utilisé plus tard pour découvrir les fuites:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid.hprof -XX:OnOutOfMemoryError=";" -XX:+UseGCOverheadLimit

Quelques points à noter ici:

  • HeapDumpOnOutOfMemoryError indique à la JVM de vider le tas dans un fichier physique en cas d' OutOfMemoryError
  • HeapDumpPath indique le chemin où le fichier doit être écrit; n'importe quel nom de fichier peut être donné; cependant, si JVM trouve undans le nom, l'ID de processus du processus en cours à l'origine de l'erreur de mémoire insuffisante sera ajouté au nom du fichier au format .hprof
  • OnOutOfMemoryError est utilisé pour émettre des commandes d'urgence à exécuter en cas d'erreur de mémoire insuffisante; la commande appropriée doit être utilisée dans l'espace des arguments cmd. Par exemple, si nous voulons redémarrer le serveur dès qu'un manque de mémoire survient, nous pouvons définir le paramètre:
-XX:OnOutOfMemoryError="shutdown -r"
  • UseGCOverheadLimit est une stratégie qui limite la proportion de temps de la VM qui est passé dans GC avant qu'uneerreur OutOfMemory ne soit générée

6. 32/64 bits

Dans l'environnement du système d'exploitation où les packages 32 et 64 bits sont installés, la JVM choisit automatiquement les packages d'environnement 32 bits.

Si nous voulons définir manuellement l'environnement sur 64 bits, nous pouvons le faire en utilisant le paramètre ci-dessous:

-d

Le bit du système d'exploitation peut être 32 ou 64 . Vous trouverez plus d'informations à ce sujet ici.

7. Divers

  • -server : active «Server Hotspot VM»; ce paramètre est utilisé par défaut dans la JVM 64 bits
  • -XX: + UseStringDeduplication : Java 8u20 a introduit ce paramètre JVM pour réduire l'utilisation inutile de la mémoire en créant trop d'instances de la même chaîne; cela optimise la mémoire du tas en réduisant lesvaleurs de chaîne en doubleà un seul tableau global char []
  • -XX: + UseLWPSynchronization : définit lapolitique de synchronisation basée sur LWP ( Light Weight Process ) au lieu de la synchronisation basée sur les threads
  • -XX: LargePageSizeInBytes : définit la grande taille de page utilisée pour le tas Java; il prend l'argument en Go / Mo / Ko; avec des pages de plus grande taille, nous pouvons mieux utiliser les ressources matérielles de la mémoire virtuelle; cependant, cela peut entraîner des tailles d'espace plus grandes pour PermGen , ce qui peut forcer à réduire la taille de l'espace de tas Java
  • -XX: MaxHeapFreeRatio : définit le pourcentage maximum de tas libre après GC pour éviter la réduction.
  • -XX: MinHeapFreeRatio : définit le pourcentage minimum de tas libre après GC pour éviter l'expansion; pour surveiller l'utilisation du tas, vous pouvez utiliser VisualVM livré avec JDK.
  • -XX: SurvivorRatio : Ratio de la taille de l'espace eden / survivant - par exemple, -XX: SurvivorRatio = 6 définit le rapport entre chaque espace survivant et espace eden à 1: 6,
  • -XX: + UseLargePages : utilise la mémoire de grandes pages si elle est prise en charge par le système; veuillez noter qu'OpenJDK 7 a tendance à planter si vous utilisez ce paramètre JVM

  • -XX: + UseStringCache : active la mise en cache des chaînes couramment allouées disponibles dans lepool de chaînes

  • -XX: + UseCompressedStrings : utilise un type byte [] pour lesobjets String qui peuvent être représentés au format ASCII pur
  • -XX: + OptimizeStringConcat : il optimise lesopérations de concaténation de chaînes lorsque cela est possible

8. Conclusion

Dans cet article rapide, nous avons découvert certains paramètres JVM importants, qui peuvent être utilisés pour régler et améliorer les performances générales des applications.

Certains d'entre eux peuvent également être utilisés à des fins de débogage.

Si vous souhaitez explorer les paramètres de référence plus en détail, vous pouvez commencer ici.