Maison > Java > javaDidacticiel > Gestion de la mémoire JVM------Garbage collector affiné (vous permettant de jouer en toute simplicité dans le monde des garbage collectors)

Gestion de la mémoire JVM------Garbage collector affiné (vous permettant de jouer en toute simplicité dans le monde des garbage collectors)

黄舟
Libérer: 2016-12-28 15:51:34
original
1135 Les gens l'ont consulté

Introduction

Dans le chapitre précédent, nous avons discuté de l'implémentation du garbage collector sur hotspot. Il existe un total de six implémentations et six combinaisons. Cette fois, LZ discutera avec vous de la puissance de chacun de ces six collectionneurs et de la puissance de leur combinaison.
Afin de faciliter votre visualisation et comparaison, LZ a décidé d'utiliser la méthode utilisée lors de la rédaction du design pattern, et d'expliquer ces collectionneurs en plusieurs dimensions pour certains collectionneurs.

Mode client et mode serveur

Avant de présenter le contenu de ce chapitre, permettez-moi de parler des deux modes de JVM, l'un est le mode client et l'autre est le mode serveur. Le mode que nous utilisons habituellement pour le développement est le mode client par défaut. Vous pouvez également utiliser le paramètre de ligne de commande -server pour forcer l'activation du mode serveur. La plus grande différence entre les deux est que la JVM a effectué de nombreuses optimisations sur le serveur. mode.
Les applications JAVA en mode serveur démarrent lentement, mais en raison de l'optimisation de la JVM en mode serveur, la vitesse d'exécution deviendra de plus en plus rapide lorsque le programme s'exécute pendant une longue période. Au contraire, bien que les applications JAVA en mode client démarrent rapidement, elles ne sont pas adaptées à une exécution à long terme. Si la durée d'exécution est longue, les performances seront nettement inférieures à celles du mode serveur.

Explication détaillée des collecteurs

Ci-dessous, nous discuterons d'abord du contenu pertinent d'un seul garbage collector, et enfin nous parlerons brièvement des caractéristiques de chaque combinaison après combinaison.

Serial Garbage Collector

Algorithme : utilisation d'un algorithme de copie
Zone mémoire : conçue pour la nouvelle génération
Méthode d'exécution : monothread, série
Processus d'exécution : nouvelle génération Quand la mémoire n'est pas suffisante, suspendez d'abord tous les programmes utilisateur, puis démarrez un thread GC pour utiliser l'algorithme de copie pour collecter les ordures. Dans ce processus, certains objets peuvent être promus à l'ancienne génération
Caractéristiques : En raison du monothread. opération, et l'ensemble du GC Le programme utilisateur doit être mis en pause à chaque étape, ce qui entraînera une longue pause de l'application, mais cela convient très bien aux programmes à petite échelle.
Scénarios applicables : utilisation quotidienne du programme de développement et de débogage, ainsi que des programmes interactifs d'applications de bureau.
Paramètres d'ouverture : -XX : UseSerialGC (valeur par défaut du mode client)

Serial Old Garbage Collector

Ici nous ne listons plus les caractéristiques de chaque dimension pour l'ancien collecteur de série, car il est différent du série Le collecteur est le même, la différence est qu'il est conçu pour l'ancienne génération et utilise donc un algorithme de marquage/collage. Pour le reste des caractéristiques dimensionnelles, l'ancien série est exactement le même que le collecteur série.

ParNew Garbage Collector

Algorithme : utilisant un algorithme de copie
Zone mémoire : conçue pour la nouvelle génération
Méthode d'exécution : multithread, parallèle
Processus d'exécution : génération actuelle mémoire Lorsque cela ne suffit pas, suspendez d'abord tous les programmes utilisateur, puis démarrez plusieurs threads GC pour utiliser l'algorithme de copie pour effectuer le garbage collection en parallèle. Au cours de ce processus, certains objets peuvent être promus à l'ancienne génération
Caractéristiques : Multi. -les threads sont utilisés pour fonctionner en parallèle, donc cela dépend du nombre de processeurs centraux dans le système. Au moins plus d'un processeur est requis. Plusieurs processeurs ouvriront plusieurs threads (mais le nombre de threads peut être contrôlé à l'aide). le paramètre -XX:ParallelGCThreads=), il ne convient donc qu'aux systèmes multicœurs et multiprocesseurs. Bien que le programme utilisateur doive encore être mis en pause pendant toute la phase GC, le traitement parallèle multithread ne provoquera pas une pause trop longue. Par conséquent, en termes de débit, ParNew est supérieur à la série. Plus il y a de processeurs, plus l'effet est évident. Mais ce n'est pas absolu. Pour un seul processeur, les performances de ParNew seront inférieures à celles du collecteur série en raison de la surcharge de l'exécution parallèle (telle que la synchronisation). Non seulement lors de l'utilisation d'un seul processeur, mais également lors de l'utilisation d'un tas de plus petite capacité, ou même lors de l'utilisation de deux processeurs, les performances de ParNew ne sont pas nécessairement supérieures à celles du série.
Scénario applicable : sur un tas moyen à grand, et le système dispose d'au moins un processeur
Activer les paramètres : -XX : UseParNewGC

Parallel Scavenge Garbage Collector

Ce collecteur est presque identiques à ParNew. Ce sont tous deux des collecteurs parallèles conçus pour la nouvelle génération et utilisant des algorithmes de réplication. La plus grande différence entre ParNew et ParNew est que les paramètres réglables sont différents, ce qui nous permet de contrôler plus précisément le temps de pause et le débit du GC.
Les paramètres fournis par le collecteur de récupération parallèle incluent principalement le contrôle du temps de pause maximum (en utilisant -XX:MaxGCPauseMillis=) et le contrôle du débit (en utilisant -XX:GCTimeRatio=). Il ressort de cela que le nettoyage parallèle est un collecteur qui assure le contrôle du débit.
Mais ne pensez pas que plus le temps de pause maximum est petit, meilleur est le débit, ou plus le débit est élevé, mieux c'est. Lors de l'utilisation du collecteur de récupération parallèle, il existe trois indicateurs de performance principaux : le temps de pause maximum, le débit et le nouveau. zone de génération.
Le collecteur de récupération parallèle a une stratégie d'ajustement correspondante. Il donnera la priorité à l'atteinte de l'objectif de temps de pause maximum, suivi du débit, et enfin de la valeur minimale de la zone de nouvelle génération.
Par conséquent, si vous définissez un temps de pause maximum trop court, vous sacrifierez le débit global et la taille de la nouvelle génération pour satisfaire vos désirs égoïstes. Les paumes et le dos de nos mains sont pleins de chair, nous ferions donc mieux de ne pas faire cela. Cependant, le nettoyage parallèle a un paramètre qui permet au collecteur de nettoyage parallèle de prendre entièrement en charge l'ajustement de la taille de la zone mémoire. Cela inclut également l'âge de promotion vers l'ancienne génération (peut être ajusté à l'aide de -XX:MaxTenuringThreshold=n), cela. Autrement dit, utilisez -XX : UseAdaptiveSizePolicy active la stratégie adaptative de taille de zone mémoire.
Le collecteur de récupération parallèle peut être activé à l'aide du paramètre -XX : UseParallelGC. C'est également le collecteur nouvelle génération par défaut en mode serveur.

Parallel Old Garbage Collector

La relation entre Parallel Old et ParNew ou Parallel Scavenge est comme la série et la série Old. La différence entre eux n'est pas grande, mais l'ancien parallèle est destiné aux personnes âgées. n'est qu'un collecteur parallèle conçu dans les temps modernes, il utilise donc un algorithme de marquage/collage.
Une autre signification importante du collecteur Parallel Old est qu'il s'agit du seul collecteur d'ancienne génération autre que l'ancien en série qui peut fonctionner avec le nettoyage parallèle. Par conséquent, afin d'éviter que l'ancien collecteur en série n'affecte la réputation du débit contrôlable du nettoyage parallèle, parallèle. old est un véritable partenaire du nettoyage parallèle.
Il peut être activé à l'aide du paramètre -XX:-UseParallelOldGC, mais après JDK6, c'est également le collecteur d'ancienne génération par défaut après avoir activé le nettoyage parallèle.

Récupérateur de place par balayage de marque simultané

Le collecteur de balayage de marque simultané (ci-après dénommé CMS) est le seul qui implémente véritablement les applications et les threads GC pour travailler ensemble (ensemble pour les clients, et il n'est pas nécessairement vrai ensemble, il peut s'agir d'un collectionneur à alternance rapide.
CMS est un collecteur conçu pour l'ancienne génération et utilise un algorithme de marquage/effacement. C'est également le seul collecteur qui utilise un algorithme de marquage/effacement de l'ancienne génération.
L'algorithme Mark/Clear est utilisé en raison de sa méthode de traitement spéciale, divisée en quatre étapes.
1. Marquage initial : Il est nécessaire de mettre l'application en pause et de marquer rapidement les objets survivants.
2. Marquage simultané : restaurez l'application et suivez les racines GC simultanément.
3. Re-marquer : vous devez mettre l'application en pause et re-marquer les objets manqués par le suivi.
4. Effacement simultané : restaurez l'application et effacez simultanément les objets indésirables non marqués.
C'est un peu plus compliqué que l'algorithme de marquage/effacement original. Cela se reflète principalement dans les deux phases de marquage simultané et de compensation simultanée. Ces deux phases sont également les phases les plus longues de toute la phase GC. , en raison de ces deux étapes, les étapes sont exécutées simultanément avec l'application, le temps de pause provoqué par le collecteur CMS est donc très court. C’est relativement facile à comprendre.
Cependant, ses défauts doivent être brièvement évoqués, les principaux sont les suivants.

1. Étant donné que le thread GC et le programme d'application saisiront les ressources du processeur lorsqu'ils seront exécutés simultanément, le débit global diminuera. En d'autres termes, en termes d'indicateurs de débit, le collecteur CMS est plus faible que le collecteur de récupération parallèle. LZ extrait ici une description du CMS du site officiel d'Oracle, qui mentionne la relation entre les performances du CMS et le nombre de processeurs.
Étant donné qu'au moins un processeur est utilisé pour le garbage collection pendant les phases simultanées, le collecteur simultané n'apporte normalement aucun avantage sur une machine monoprocesseur (monocœur). Cependant, il existe un mode distinct disponible qui peut réaliser de faibles pauses. sur les systèmes avec seulement un ou deux processeurs ; voir le mode incrémental ci-dessous pour plus de détails.

L'anglais de LZ est très moyen (je n'ai pas passé le niveau 4, dommage, 0,0), mais je peux le traduire grossièrement avec l'aide des outils La signification de ce passage est la suivante.
L'essentiel en chinois : étant donné que le garbage collection dans la phase simultanée utilise au moins un processeur, vous ne bénéficierez d'aucun avantage en utilisant un collecteur simultané sur un seul processeur. Cependant, il existe un moyen indépendant d'obtenir efficacement de faibles pauses sur les systèmes à un ou deux processeurs. Voir le mode incrémentiel ci-dessous pour plus de détails.
Évidemment, la documentation d'Oracle souligne que dans le cas d'un seul processeur, le collecteur concurrent entraînera une dégradation des performances due à la préemption du processeur. Enfin, une manière de gérer le mode incrémental est donnée, mais il est souligné dans le livre « Compréhension approfondie de la machine virtuelle JAVA » que le mode incrémental a été défini comme non recommandé. Étant donné que l'introduction officielle extraite de LZ est basée sur l'introduction du JDK5.0 et que le livre « Compréhension approfondie de la machine virtuelle JAVA » fait référence à la version du JDK6.0, LZ devine provisoirement que le mode incrémentiel est dans le JDK6. 0 Il a été abandonné lors de sa sortie, mais l'heure ou la version de cet abandon n'a en réalité plus d'importance.
2. Un gros inconvénient de mark/clear est l’existence d’une fragmentation de la mémoire. Par conséquent, la JVM fournit le paramètre -XX: UseCMSCompactAtFullCollection pour effectuer le travail de défragmentation après le GC global (GC complet). Étant donné que la défragmentation après chaque GC global affectera grandement le temps de pause, la JVM fournit également le paramètre - XX:CMSFullGCsBeforeCompaction pour contrôler le GC global. défragmentation après plusieurs GC globaux.
3. La dernière lacune du CMS implique un terme : « Concurrent Mode Failure ». C'est l'explication officielle de ce terme.
si le collecteur concurrent n'est pas en mesure de terminer la récupération des objets inaccessibles avant que la génération titulaire ne soit remplie, ou si une allocation ne peut pas être satisfaite avec les blocs d'espace libre disponibles dans la génération titulaire, alors l'application est suspendue et la collecte est complétée avec tous les objets inaccessibles. les threads d'application se sont arrêtés. L'incapacité de terminer une collection simultanément est appelée échec du mode concurrent et indique la nécessité d'ajuster les paramètres du collecteur simultané.
Signification chinoise : si le collecteur simultané ne peut pas se terminer avant que l'ancienne génération ne soit remplie, il est Le recyclage des objets inaccessibles (inaccessibles), ou l'espace mémoire libre effectif dans l'ancienne génération ne peut pas satisfaire une certaine demande d'allocation de mémoire, à ce moment-là, l'application sera suspendue et le garbage collection démarrera pendant cette période de suspension. repris jusqu'à ce que le recyclage soit terminé. Cet échec de la collecte simultanée est appelé échec du mode concurrent, et l'apparition de cette situation signifie également que nous devons ajuster les paramètres du collecteur concurrent.
Les deux situations ci-dessus semblent un peu répétitives. L'échec de la satisfaction de la demande d'allocation de mémoire n'est-il pas causé par l'échec du recyclage des objets avant que l'ancienne génération ne soit remplie ?
La compréhension personnelle de LZ ici est que l'incapacité de terminer le recyclage des objets avant que l'ancienne génération ne soit remplie signifie que l'ancienne génération n'est pas effacée à temps pendant la phase d'effacement simultanée, ce qui entraîne une mémoire libre insuffisante. L'incapacité de satisfaire les demandes d'allocation de mémoire fait principalement référence au fait que lorsque la nouvelle génération est promue à l'ancienne génération, en raison d'un trop grand nombre de fragments de mémoire dans l'ancienne génération, certaines allocations ne peuvent pas être satisfaites car il n'y a pas de mémoire continue.
En fait, lorsque le mode concurrent échoue, Serial Old sera utilisé comme collecteur alternatif pour effectuer un GC global (Full GC), donc Serial Old peut également être considéré comme un "substitut" au CMS. Évidemment, en raison de l'intervention de l'ancien série, un temps de pause important sera provoqué.
Afin d'éviter autant que possible les échecs du mode simultané, nous pouvons ajuster le paramètre -XX:CMSInitiatingOccupancyFraction= pour contrôler la quantité d'utilisation de la mémoire de l'ancienne génération atteinte (N%), puis démarrer le mode simultané. collecteur pour se lancer dans le recyclage ancienne génération.

Le pouvoir des combinaisons

Nous avons brièvement présenté les caractéristiques de chaque collectionneur ci-dessus, LZ partagera avec vous trois combinaisons typiques. Les trois autres combinaisons ne sont généralement pas couramment utilisées.

série & série ancienne

Cette combinaison est l'une de nos combinaisons les plus courantes et est également la combinaison de garbage collector par défaut en mode client. Vous pouvez également utiliser le paramètre -XX : UseSerialGC pour le forcer. sur.
Parce qu'il est relativement simple à mettre en œuvre et n'entraîne aucune surcharge supplémentaire liée aux threads (principalement la commutation et la synchronisation des threads), il est très approprié pour les petites applications exécutées sur le PC client ou les applications de bureau (telles que les programmes d'interface utilisateur écrits en swing), ainsi que nos habituels développements, débogages, tests, etc.
Les trois situations ci-dessus ont toutes des caractéristiques communes.
1. Comme ils fonctionnent tous sur PC, la configuration n'est généralement pas trop élevée, ni le nombre de processeurs n'est pas trop important.
2. Les applications dans les situations ci-dessus ne fonctionneront pas trop longtemps.
3. L'échelle ne sera pas trop grande, c'est-à-dire que le tas sera relativement petit, la collecte sera plus rapide et le temps de pause sera plus court.

Parallel Scavenge & Parallel Old

Cette combinaison n'est pas courante chez nous Après tout, elle n'apparaît pas dans notre développement habituel, mais c'est une combinaison qui nécessite un débit élevé ou la première. choix pour les applications qui ne nécessitent pas de temps de pause élevé (temps de pause), et cette combinaison est la combinaison par défaut en mode serveur (JDK6 ou après JDK6). Bien entendu, il peut également être activé de force à l'aide du paramètre -XX : UseParallelGC.
Cette combinaison utilise une collecte parallèle à la fois dans la nouvelle génération et dans l'ancienne génération, de sorte que le temps de pause est plus court et que le débit global du système est plus élevé. Il convient à certains programmes d'arrière-plan qui doivent s'exécuter pendant une longue période et qui ont certaines exigences en matière de débit.
Ces programmes exécutés en arrière-plan présentent les caractéristiques suivantes.
1. La configuration du système est relativement élevée, généralement au moins quatre cœurs (en fonction du niveau matériel actuel).
2. Les exigences de débit sont élevées ou un certain montant doit être atteint.
3. L'application met beaucoup de temps à s'exécuter.
4. La taille de l'application est grande, généralement un tas moyen à grand.

ParNew & CMS (Serial Old en remplacement)

Cette combinaison est la même que la combinaison parallèle ci-dessus. Elle n'est pas courante dans le développement quotidien, et c'est pour le temps de réponse le premier choix. pour des applications plus exigeantes. Cette combinaison doit être activée à l'aide du paramètre -XX : UseConcMarkSweepGC.
Cette combinaison utilise un collecteur parallèle dans la nouvelle génération, donc la vitesse GC de la nouvelle génération sera très rapide et le temps de pause sera très court. Le GC de la jeune génération utilise une collecte simultanée.Pendant la majeure partie du temps de garbage collection, le thread GC est exécuté en même temps que l'application, le temps de pause est donc encore très court. Il convient à certains programmes d'arrière-plan qui doivent s'exécuter pendant une longue période et qui ont certaines exigences en matière de temps correspondant.
Les caractéristiques de ces programmes exécutés en arrière-plan sont très similaires aux programmes d'arrière-plan en mode parallèle. La différence réside dans le deuxième point. Les applications en arrière-plan utilisant la combinaison de ParNew et de CMS ont généralement certaines exigences en matière de temps de réponse. Ceci est notre application WEB.

Conclusion

Cette fois, LZ a trié les caractéristiques de chaque collecteur et les caractéristiques de chaque combinaison. De plus, il reste trois combinaisons que LZ n'a pas mentionnées ici. La raison en est que ces trois combinaisons ne sont pas particulièrement utilisées, ou peuvent l'être. a dit qu'elles sont à peine utilisées. Ces trois combinaisons donnent toutes aux gens un sentiment différent, et l'effet n'est en effet pas bon.
J'espère que cet article pourra vous apporter un peu d'aide, merci d'avoir regardé.

Ce qui précède est le contenu de la gestion de la mémoire JVM------raffinement du garbage collector (vous permettant de jouer facilement dans le monde du garbage collector. Pour plus de contenu connexe, veuillez faire attention au PHP). Site chinois (www .php.cn) !


Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal