Garbage Collectors JVM

1. Vue d'ensemble

Dans ce rapide didacticiel, nous montrerons les bases des différentes implémentations de JVM Garbage Collection (GC) . De plus, nous découvrirons comment activer un type particulier de nettoyage de la mémoire dans nos applications.

2. Brève introduction à la collecte des ordures

Du nom, il ressemble collecte des ordures traite de trouver et de supprimer les déchets de la mémoire. Cependant, en réalité, Garbage Collection suit chaque objet disponible dans l'espace de tas JVM et supprime ceux qui ne sont pas utilisés.

En termes simples, GC fonctionne en deux étapes simples connues sous le nom de Mark and Sweep:

  • Mark - c'est là que le ramasse-miettes identifie les morceaux de mémoire utilisés et ceux qui ne le sont pas
  • Balayage - cette étape supprime les objets identifiés lors de la phase de «marquage»

Avantages:

  • Pas de gestion manuelle d'allocation / désallocation de mémoire car l'espace mémoire inutilisé est automatiquement géré par GC
  • Pas de frais généraux de manipulation du pointeur suspendu
  • Gestion automatique des fuites de mémoire ( GC à lui seul ne peut pas garantir la solution de preuve complète aux fuites de mémoire, cependant, il en prend en charge une bonne partie)

Désavantages:

  • Étant donné que JVM doit suivre la création / suppression de la référence d'objet, cette activité nécessite plus de puissance CPU que l'application d'origine. Cela peut affecter les performances des requêtes nécessitant une grande mémoire
  • Les programmeurs n'ont aucun contrôle sur la planification du temps CPU dédié à la libération d'objets qui ne sont plus nécessaires
  • L'utilisation de certaines implémentations GC peut entraîner l'arrêt de l'application de manière imprévisible
  • La gestion automatisée de la mémoire ne sera pas aussi efficace que l'allocation / la désallocation manuelle appropriée de la mémoire

3. Implémentations du GC

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

3.1. Collecteur de déchets série

Il s'agit de l'implémentation GC la plus simple, car elle fonctionne essentiellement avec un seul thread. En conséquence, cette implémentation GC gèle tous les threads d'application lors de son exécution . Par conséquent, ce n'est pas une bonne idée de l'utiliser dans des applications multithreads comme les environnements de serveur.

Cependant, les ingénieurs de Twitter ont eu un excellent discours à QCon 2012 sur les performances de Serial Garbage Collector - ce qui est un bon moyen de mieux comprendre ce collecteur.

Serial GC est le ramasse-miettes de choix pour la plupart des applications qui ne nécessitent pas de temps de pause réduit et qui s'exécutent sur des machines de type client. Pour activer Serial Garbage Collector , nous pouvons utiliser l'argument suivant:

java -XX:+UseSerialGC -jar Application.java

3.2. Collecteur d'ordures parallèle

C'est le GC par défaut de la JVM et parfois appelé Collecteurs de débit. Contrairement à Serial Garbage Collector , il utilise plusieurs threads pour gérer l'espace du tas . Mais il gèle également d'autres threads d'application lors de l'exécution de GC .

Si nous utilisons ce GC , nous pouvons spécifier le nombre maximal de threads de garbage collection et le temps de pause, le débit et l'empreinte (taille du tas).

Le nombre de threads de ramasse-miettes peut être contrôlé avec l'option de ligne de commande -XX: ParallelGCThreads = .

L'objectif de temps de pause maximal (intervalle [en millisecondes] entre deux GC ) est spécifié avec l'option de ligne de commande -XX: MaxGCPauseMillis = .

L'objectif de débit maximal (mesuré en fonction du temps passé à effectuer le garbage collection par rapport au temps passé en dehors du garbage collection) est spécifié par l'option de ligne de commande -XX: GCTimeRatio =.

L'encombrement maximal du tas (la quantité de mémoire de tas dont un programme a besoin lors de l'exécution) est spécifié à l'aide de l'option -Xmx.

Pour activer Parallel Garbage Collector , nous pouvons utiliser l'argument suivant:

java -XX:+UseParallelGC -jar Application.java

3.3. Collecteur de déchets CMS

L' implémentation CMS (Concurrent Mark Sweep) utilise plusieurs threads de garbage collector pour le garbage collection. Il est conçu pour les applications qui préfèrent des pauses de garbage collection plus courtes et qui peuvent se permettre de partager les ressources du processeur avec le garbage collector pendant que l'application est en cours d'exécution.

En termes simples, les applications utilisant ce type de GC répondent plus lentement en moyenne mais ne cessent pas de répondre pour effectuer un garbage collection.

Un point rapide à noter ici est que puisque ce GC est simultané, une invocation de garbage collection explicite comme l'utilisation de System.gc () pendant que le processus simultané fonctionne, entraînera une panne / interruption du mode simultané .

Si plus de 98% du temps total est passé dans le garbage collection CMS et que moins de 2% du tas est récupéré, une OutOfMemoryError est générée par le collecteur CMS . Si nécessaire, cette fonctionnalité peut être désactivée en ajoutant l'option -XX: -UseGCOverheadLimit à la ligne de commande.

Ce collecteur a également un mode connu sous le nom de mode incrémentiel qui est en train d'être obsolète dans Java SE 8 et peut être supprimé dans une future version majeure.

Pour activer le CMS Garbage Collector , nous pouvons utiliser l'indicateur suivant:

java -XX:+UseParNewGC -jar Application.java

Depuis Java 9, le garbage collector CMS est obsolète . Par conséquent, JVM imprime un message d'avertissement si nous essayons de l'utiliser:

>> java -XX:+UseConcMarkSweepGC --version Java HotSpot(TM) 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release. java version "9.0.1"

De plus, Java 14 a complètement abandonné le support CMS:

>> java -XX:+UseConcMarkSweepGC --version OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; support was removed in 14.0 openjdk 14 2020-03-17

3.4. Garbage Collector G1

G1 (Garbage First) Garbage Collector est conçu pour les applications exécutées sur des machines multiprocesseurs avec un grand espace mémoire. Il est disponible depuis JDK7 Update 4 et dans les versions ultérieures.

Le collecteur G1 remplacera le collecteur CMS car il est plus performant.

Unlike other collectors, G1 collector partitions the heap into a set of equal-sized heap regions, each a contiguous range of virtual memory. When performing garbage collections, G1 shows a concurrent global marking phase (i.e. phase 1 known as Marking) to determine the liveness of objects throughout the heap.

After the mark phase is completed, G1 knows which regions are mostly empty. It collects in these areas first, which usually yields a significant amount of free space (i.e. phase 2 known as Sweeping). It is why this method of garbage collection is called Garbage-First.

To enable the G1 Garbage Collector, we can use the following argument:

java -XX:+UseG1GC -jar Application.java

3.5. Java 8 Changes

Java 8u20 a introduit un paramètre JVM supplémentaire 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 supprimant les valeurs de chaîne en double dans un tableau global unique char [] .

Ce paramètre peut être activé en ajoutant -XX: + UseStringDeduplication comme paramètre JVM .

4. Conclusion

Dans ce rapide tutoriel, nous avons examiné les différentes implémentations de JVM Garbage Collection et leurs cas d'utilisation.

Une documentation plus détaillée peut être trouvée ici.