Partage de technologie

[Bases de la JVM] Introduction au Garbage Collector Java

2024-07-11

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Garbage collector (implémentation de l'algorithme de collecte des déchets)

Le garbage collector est l'implémentation spécifique de l'algorithme de garbage collection . Puisque le garbage collector est divisé en jeune génération et ancienne génération, en plus de G1 (qui peut contrôler à la fois la nouvelle génération et l'ancienne génération),Les éboueurs nouvelle génération et ancienne génération doivent être utilisés par paires selon les exigences du hotspot.(Vous devez choisir la combinaison correspondante selon la version du JDK)

La relation de combinaison spécifique est la suivante :

Insérer la description de l'image ici

Dans le code source sous-jacent de la JVM, dans certains cas particuliers, le recycleur CMS appellera le recycleur Serial Old.

Arthas voit le ramasse-miettes utilisé

Vous ne pouvez pas voir directement quel garbage collector est utilisé, vous pouvez uniquement le déduire en fonction de l'algorithme.

Insérer la description de l'image ici

Éboueur en série de jeune génération

La série est unCollection en série monothread de la jeune générationLe éboueur.

Insérer la description de l'image ici

Âges et algorithmes du recyclage

  • jeune génération
  • Algorithme de réplication

avantage

Excellent débit sur un seul processeur CPU

défaut

Le débit sous multi-CPU n'est pas aussi bon que celui des autres ramasse-miettes (mono-thread, utilisant un seul processeur). Si le tas est trop volumineux, le thread utilisateur attendra longtemps.

Scène applicable

Programmes clients écrits en Java ou scénarios avec une configuration matérielle limitée (peu de cœurs de processeur)

comment utiliser

-XX: UseSerialGC: La nouvelle génération et l'ancienne génération utilisent le collecteur en série.

Ancienne génération-SerialOld garbage collector

SerialOld est la version ancienne génération du garbage collector Serial, utilisantCollection en série monothread

Insérer la description de l'image ici

Âges et algorithmes du recyclage

  • vieillesse
  • Algorithme de regroupement de marques

avantage

Excellent débit sur un seul processeur CPU

défaut

Le débit sous multi-CPU n'est pas aussi bon que celui des autres garbage collectors. Si le tas est trop volumineux, le thread utilisateur attendra longtemps.

Scène applicable

Utilisé avec le garbage collector série ou dans des cas particuliers CMS

comment utiliser

-XX: UseSerialGC: La nouvelle génération et l'ancienne génération utilisent le collecteur en série.

Jeune génération-ParNew éboueur

Le garbage collector ParNew est essentiellementOptimisation du Serial sous plusieurs CPU, en utilisant le multi-thread pour le garbage collection

Insérer la description de l'image ici

Âge de recyclage et algorithme :

  • jeune génération
  • Algorithme de réplication

avantage

  • Temps de pause plus courts sous les processeurs multi-CPU

défaut

  • Le débit et le temps de pause ne sont pas aussi bons que G1, ce n'est donc pas recommandé après JDK9

Scène applicable

  • Dans JDK8 et les versions précédentes, il est utilisé conjointement avec le garbage collector CMS ancienne génération.

comment utiliser

  • -XX: UseParNewGC: La nouvelle génération utilise le collecteur ParNew et l'ancienne génération utilise le collecteur série.

Insérer la description de l'image ici

Récupérateur de place ancienne génération CMS (Concurrent Mark Sweep)

Le garbage collector du CMS se concentre sur le temps de pause du système (pour minimiser STW et optimiser l'expérience utilisateur),Autoriser les threads utilisateur et les threads de garbage collection à s'exécuter simultanément à certaines étapes, réduisant le temps d'attente des threads utilisateur.

Âges et algorithmes du recyclage

  • vieillesse
  • Algorithme de marquage et de balayage

avantage

  • Le temps de pause du système dû au garbage collection est plus court et l'expérience utilisateur est meilleure.

défaut

1. Problème de fragmentation de la mémoire

2. Problème de dégradation (dans certains cas précis, il dégénérera en un collecteur mono-thread tel que SerialOld)

3. Problème de déchets flottants (certains déchets ne peuvent pas être recyclés pendant le processus de recyclage)

Scène applicable

Scénarios dans des systèmes Internet à grande échelle dans lesquels les utilisateurs demandent de grandes quantités de données et à haute fréquence, tels que des interfaces de commande, des interfaces de produits, etc.

utiliser

XX: UseConcMarkSweepGC, vous pouvez définir respectivement les collectionneurs de la jeune génération et de l'ancienne génération.

Insérer la description de l'image ici

Insérer la description de l'image ici

Étapes d'exécution du CMS

  1. Marquage initial, balisage en très peu de tempsObjets auxquels les racines GC peuvent directement se rapporter
  2. marquage simultané, Marquer tous les objets , le thread utilisateur n'a pas besoin d'être mis en pause. (Bien que le marquage simultané soit exécuté avec le thread utilisateur, si les ressources occupées par le marquage simultané sont élevées, cela affectera également le thread utilisateur)
  3. Remarque (concurrence), car certains objets changeront pendant la phase de marquage simultanée, il y aura un mauvais étiquetage (l'objet utilisé était à l'origine vivant, mais après le marquage, le thread utilisateur l'a rendu non viable, ce qui entraînera un mauvais étiquetage), un étiquetage manquant (Parce que c'est concurrent, certains objets peuvent avoir été créés par le thread utilisateur, ce qui entraînera des balises manquantes) et d'autres situations, et doivent être remarqués.
  4. Nettoyage simultané, nettoyage des objets morts, les threads utilisateur n'ont pas besoin d'être mis en pause.

Remarque : STW n'apparaîtra que pendant les phases initiales de marquage et de remarquage.

Insérer la description de l'image ici

défaut:

1. CMS utilise un algorithme de marquage et d'effacement une fois le garbage collection terminé, un grand nombre de fragments de mémoire apparaîtront afin de ne pas affecter l'allocation des objets.CMS sera défragmenté pendant le GC complet. . Cela entraînera une pause du fil utilisateur,Vous pouvez utiliser le paramètre -XX:CMSFullGCsBeforeCompaction=N (par défaut 0) pour ajuster le Full GC N fois avant de le trier.

2. Impossible de gérer les « déchets flottants » générés pendant le processus de nettoyage simultané et impossible de réaliser un garbage collection complet (au cours de ce processus de nettoyage, le thread utilisateur a créé simultanément certains objets, mais ils n'ont pas été réutilisés bientôt. Ces objets ne sont pas recyclé lors de ce nettoyage et doit attendre le prochain nettoyage, c'est pourquoi on l'appelle déchet flottant).

3. S'il n'y a pas suffisamment de mémoire dans l'ancienne génération pour allouer des objets, le CMS dégénérera en Serial Old monothread recyclant l'ancienne génération.

Nombre de threads simultanés :

Le nombre de threads lors de l'exécution de la phase simultanée dans le CMS peut être transmis-XX:ConcGCThreadsLes réglages des paramètres sont calculés par le système et la formule de calcul est la suivante :(-XX:ParallelGCThreads定义的线程数 3) / 4, ParallelGCThreads est le nombre de threads parallèles après la pause STW

ParallelGCThreads est déterminé par le nombre de cœurs de processeur :

1. Lorsque le nombre de cœurs de processeur est inférieur à 8, ParallelGCThreads = Nombre de cœurs de processeur

2. Sinon ParallelGCThreads = 8 (Nombre de cœurs de processeur – 8)*5/8

Il y a 12 processeurs logiques sur mon ordinateur, donc ParallelGCThreads = 8 (12 - 8) * 5/8 = 10, ConcGCThreads = (-XX : Le nombre de threads défini par ParallelGCThreads 3) / 4 = (10 3) / 4 = 3

Insérer la description de l'image ici

Finalement, vous pouvez obtenir cette image :

Insérer la description de l'image ici

Les phases de marquage et de nettoyage simultanées seront traitées en parallèle à l'aide de trois threads. La phase de re-marquage sera traitée à l'aide de 10 threads. Le nombre de cœurs de processeur étant limité, la phase simultanée affectera les performances d'exécution des threads utilisateur.

Insérer la description de l'image ici

Collecteur d'ordures parallèle de jeune génération

Le nettoyage parallèle estRécupérateur d'ordures de jeune génération par défaut du JDK8,MultithreadCollecte parallèleConcentrez-vous sur le débit du système .Afin d'augmenter le débit, PS vaAjuster automatiquement la taille de la mémoire du tas (ajuster la nouvelle génération, la taille de la mémoire de l'ancienne génération, le seuil de promotion)

Insérer la description de l'image ici

Âges et algorithmes du recyclage

  • jeune génération
  • Algorithme de réplication

avantage

  • Le débit est élevé et prend en charge le réglage manuel des paramètres pour contrôler le débit. Afin d'améliorer le débit, la machine virtuelle ajuste dynamiquement les paramètres du tas (l'utilisateur n'a qu'à définir le débit et n'a pas besoin de définir d'autres paramètres tels que la taille de la mémoire).

défaut

  • Il n'y a aucune garantie d'un temps de pause unique, mais il prend en charge le réglage du temps STW.

Scène applicable

  • Les tâches en arrière-plan ne nécessitent pas d'interaction de l'utilisateur et ont tendance à générer un grand nombre d'objets.Par exemple : traitement de big data, export de fichiers volumineux

Paramètres communs

Parallel Scavenge permet le réglage manuel des temps de pause et du débit maximum. Les responsables d'Oracle recommandent de ne pas définir la mémoire maximale lors de l'utilisation de cette combinaison. Le garbage collector ajustera automatiquement la taille de la mémoire en fonction du temps de pause et du débit maximum.

  • temps de pause maximum,-XX:MaxGCPauseMillis=n Définir le nombre maximum de millisecondes de pause pour chaque garbage collection
  • débit,-XX:GCTimeRatio=n Définissez le débit sur n (temps d'exécution du thread utilisateur = n/(n 1))
  • Ajuster automatiquement la taille de la mémoire, -XX: UseAdaptiveSizePolicyLe paramètre permet au garbage collector d'ajuster automatiquement la taille de la mémoire en fonction du débit et des millisecondes de pause maximales. Ce paramètre est activé par défaut (Oracle recommande que lors de l'utilisation de la combinaison PS, ne définisse pas la mémoire maximale et laisse le garbage collector s'ajuster automatiquement).

Remarque : Les deux indicateurs de temps de pause maximum et de débit sont en conflit. Le garbage collector fera de son mieux pour respecter le temps de pause maximum (parfois il est trop petit et ne peut pas être respecté, et le temps de pause maximum défini sera dépassé) , sacrifiant le débit.Si vous souhaitez définir simultanément le temps de pause et le débit maximum, vous devez effectuer davantage de tests pour les rendre plus coordonnés.

Ancienne génération-Ancien ramasse-miettes parallèle

Parallel Old est une version d'ancienne génération conçue pour le collecteur Parallel Scavenge, utilisant une collection simultanée multithread.

Insérer la description de l'image ici

Âges et algorithmes du recyclage

  • vieillesse
  • Algorithme de marquage et de tri (en fait, tri par marquage et balayage)

avantage

  • La collecte simultanée est plus efficace sous les processeurs multicœurs

défaut

  • Le temps de pause sera plus long

Scène applicable

  • Utilisé avec le nettoyage parallèle

comment utiliser

JDK8 définit les paramètres pour utiliser ce recycleur par défaut.

paramètre:-XX: UseParallelGC ou-XX: UseParallelOldGCVous pouvez utiliser la combinaison Parallel Scavenge Parallel Old.
Insérer la description de l'image ici

Insérer la description de l'image ici

test

-XX: PrintFlagsFinal: Vous pouvez imprimer les valeurs finales de tous les éléments de configuration au démarrage du programme. Vous pouvez vérifier si la fonction de réglage automatique est activée.

Insérer la description de l'image ici

Insérer la description de l'image ici

Insérer la description de l'image ici

Insérer la description de l'image ici

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 垃圾回收器案例3
 */
//-XX: UseSerialGC -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc -XX: PrintFlagsFinal
//-XX: UseParNewGC  -Xmn1g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc
//-XX: UseConcMarkSweepGC
//-XX: UseG1GC   -Xmn8g -Xmx16g -XX:SurvivorRatio=8  -XX: PrintGCDetails -verbose:gc MaxGCPauseMillis
//-XX: PrintFlagsFinal  -XX:GCTimeRatio = 19  -XX:MaxGCPauseMillis=10 -XX: UseAdaptiveSizePolicy
public class GcDemo2 {

    public static void main(String[] args) throws IOException {
        int count = 0;
        List