Maison > Java > javaDidacticiel > le corps du texte

Une brève discussion sur quelques concepts de base sur le ramasse-miettes GC de Java

高洛峰
Libérer: 2017-01-17 15:53:38
original
1318 Les gens l'ont consulté

1. Algorithme de recyclage de base

1. Comptage de références
Un algorithme de recyclage relativement ancien. Le principe est que cet objet a une référence, ce qui augmente un compte, et supprimer une référence diminue le compte. Lors du garbage collection, seuls les objets avec un nombre de 0 sont collectés. La chose la plus fatale à propos de cet algorithme est qu’il ne peut pas gérer le problème des références circulaires.
2. Mark-Sweep (Mark-Sweep)
Cet algorithme est exécuté en deux étapes. La première phase marque tous les objets référencés à partir du nœud racine de référence. La deuxième phase parcourt l'intégralité du tas et efface les objets non marqués. Cet algorithme nécessite de suspendre l’ensemble de l’application et provoque par la même occasion une fragmentation de la mémoire.
3. Copie
Cet algorithme divise l'espace mémoire en deux zones égales, et n'en utilise qu'une à la fois. Lors du garbage collection, la zone actuellement utilisée est parcourue et les objets utilisés sont copiés dans une autre zone. Cet algorithme ne traite que les objets utilisés à chaque fois, le coût de copie est donc relativement faible. En même temps, la mémoire correspondante peut être organisée après la copie, mais il existe un problème de « fragmentation ». Bien entendu, l'inconvénient de cet algorithme est également évident, c'est-à-dire qu'il nécessite deux fois plus d'espace mémoire.
4. Mark-Compact
Cet algorithme combine les avantages des algorithmes "mark-clear" et "copy". Il est également divisé en deux phases. La première phase part du nœud racine et marque tous les objets référencés. La deuxième phase parcourt l'ensemble du tas, efface les objets non marqués et « compresse » les objets survivants dans l'un des tas, et les décharge dans l'ordre. . Cet algorithme évite le problème de fragmentation du « mark-and-sweep » et évite également le problème d'espace de l'algorithme de « copie ».
5. Collecte incrémentielle (Collecte incrémentielle)
Implémentez l'algorithme de collecte des ordures, c'est-à-dire effectuez la collecte des ordures pendant que l'application est en cours. Je ne sais pas pourquoi le collecteur du JDK5.0 n'utilise pas cet algorithme.
6. Collecte générationnelle

Un algorithme de garbage collection basé sur l'analyse du cycle de vie des objets. Divisez les objets en jeune génération, ancienne génération et génération persistante, et utilisez différents algorithmes (l'une des méthodes ci-dessus) pour recycler les objets avec des cycles de vie différents. Les garbage collectors actuels (à partir de J2SE1.2) utilisent tous cet algorithme.

1. Jeune (jeune génération)
La jeune génération est divisée en trois zones. Une zone Eden et deux zones Survivant. La plupart des objets sont générés dans la zone Eden. Lorsque la zone Eden est pleine, les objets survivants seront copiés dans la zone Survivant (l'une des deux). Lorsque cette zone Survivant est pleine, les objets survivants de cette zone seront copiés dans une autre zone Survivant. , Lorsqu'elle est pleine, les objets copiés de la première zone Survivant et encore en vie à ce moment seront copiés dans la zone « Titulaire ». Il convient de noter que les deux zones du Survivant sont symétriques et n'ont aucune relation séquentielle, il peut donc y avoir des objets copiés d'Eden et des objets copiés du Survivant précédent en même temps dans la même zone. Cependant, seuls les objets copiés dans la même zone. l'ancienne zone est copiée à partir de la première. L'objet vers lequel le survivant est arrivé. De plus, l’une des zones Survivants est toujours vide.
2. Titulaires (Ancienne Génération)
L'ancienne génération stocke les objets qui survivent de la jeune génération. D’une manière générale, l’ancienne génération stocke des objets ayant une durée de vie plus longue.
3. Perm (génération persistante)
Utilisé pour stocker des fichiers statiques, maintenant des classes Java, des méthodes, etc. La génération persistante n'a pas d'impact significatif sur le garbage collection, mais certaines applications peuvent générer ou appeler dynamiquement certaines classes, comme Hibernate, etc. Dans ce cas, un espace de génération persistante relativement grand doit être configuré pour stocker ces classes nouvellement ajoutées pendant opération. La taille de la génération persistante est définie avec -XX:MaxPermSize=.


2. Types de GC
Il existe deux types de GC : Scavenge GC et Full GC.

1. Scavenge GC
Généralement, lorsqu'un nouvel objet est généré et ne parvient pas à demander de l'espace dans Eden, Scavenge GC est déclenché, la zone Eden du tas est GCed, objets de non-survie sont effacés et les objets survivants restants sont déplacés vers la zone des survivants. Organisez ensuite les deux zones de Survivor.
2. GC complet
Complétez l'ensemble du tas, y compris Young, Tenured et Perm. Full GC est plus lent que Scavenge GC, donc Full GC doit être réduit autant que possible. Les raisons suivantes peuvent provoquer un GC complet :
* Tenured est rempli
* Le champ Perm est rempli
* System.gc() est explicitement appelé
* Les champs de tas sont alloués après le dernier GC Dynamic changements de stratégie


Démonstration du processus de collecte des déchets générationnel

1.
>

2.

Une brève discussion sur quelques concepts de base sur le ramasse-miettes GC de Java

3.

Une brève discussion sur quelques concepts de base sur le ramasse-miettes GC de Java

4.

Une brève discussion sur quelques concepts de base sur le ramasse-miettes GC de Java

2. Les éboueurs


Il existe actuellement trois principaux types de collecteurs d'ordures. : Collecteur série, collecteur parallèle, collecteur concurrent.

1. Le collecteur série

utilise un seul thread pour gérer tout le travail de garbage collection, car il n'y a pas besoin d'interaction multi-thread, il est donc plus efficace. Cependant, les avantages des processeurs multiples ne sont pas disponibles, ce collecteur convient donc aux machines monoprocesseur. Bien entendu, ce collecteur peut également être utilisé sur des machines multiprocesseurs avec de petits volumes de données (environ 100M). Peut être activé avec -XX : UseSerialGC.

2. Collecteur parallèle
1. Effectuez un ramassage des ordures parallèle sur la jeune génération, réduisant ainsi le temps de ramassage des ordures. Généralement utilisé sur les machines multithreads et multiprocesseurs. Allumez avec -XX:UseParallelGC. Le collecteur parallèle a été introduit dans la sixième mise à jour de J2SE5.0 et a été amélioré dans Java SE6.0 - il peut exploiter l'ancienne génération pour la collecte parallèle. Si l'ancienne génération n'utilise pas de collecte simultanée, elle utilise un seul thread pour le garbage collection, ce qui limitera les capacités d'extension. Activez avec -XX:UseParallelOldGC.
2. Utilisez -XX:ParallelGCThreads= pour définir le nombre de threads pour le garbage collection parallèle. Cette valeur peut être définie comme étant égale au nombre de processeurs sur la machine.
3. Ce collecteur peut être configuré comme suit :
* Pause maximale du garbage collection : Spécifiez le temps de pause maximum pendant le garbage collection, spécifié par -XX:MaxGCPauseMillis=. est en millisecondes. Si cette valeur est spécifiée, la taille du tas et les paramètres liés au garbage collection seront ajustés pour atteindre la valeur spécifiée. La définition de cette valeur peut réduire le débit de votre application.
* Débit : le débit est le rapport entre le temps de collecte des déchets et le temps de non-collecte des déchets, défini par -XX:GCTimeRatio=, la formule est 1/(1 N). Par exemple, -XX:GCTimeRatio=19 signifie que 5 % du temps est utilisé pour le garbage collection. La valeur par défaut est 99, ce qui signifie que 1 % du temps est utilisé pour le garbage collection.

3. Le collecteur simultané
peut garantir que la plupart des travaux sont effectués simultanément (l'application ne s'arrête pas) et que le garbage collection n'est interrompu que pendant une courte période. Ce collecteur convient aux moyens et haut de gamme. applications qui ont des exigences de temps de réponse élevées. Application à grande échelle. Allumez avec -XX:UseConcMarkSweepGC.
1. Le collecteur simultané réduit principalement le temps de pause de l'ancienne génération. Il utilise un thread de garbage collection indépendant pour suivre les objets accessibles sans arrêter l'application. Au cours de chaque cycle de récupération de place d'ancienne génération, le collecteur simultané mettra brièvement en pause l'ensemble de l'application au début de la collecte, et s'arrêtera à nouveau pendant la collecte. La deuxième pause sera légèrement plus longue que la première, pendant laquelle plusieurs threads effectuent un travail de garbage collection en même temps.
2. Le collecteur simultané utilise le processeur en échange de courts temps de pause. Sur un système avec N processeurs, la partie de collecte simultanée utilise K/N processeurs disponibles pour le recyclage. Généralement, 13. Utilisez le collecteur simultané sur un hôte avec un seul processeur et réglez-le en mode incrémentiel pour obtenir des temps de pause plus courts.
4. Déchets flottants : étant donné que la collecte des déchets est effectuée pendant l'exécution de l'application, des déchets peuvent être générés une fois la collecte des ordures terminée, ce qui entraîne des "déchets flottants". Ces déchets doivent être recyclés lors du prochain cycle de collecte des ordures. . Perdre. Par conséquent, le collecteur simultané nécessite généralement 20 % d'espace réservé pour ces déchets flottants.
5. Échec du mode simultané : le collecteur simultané collecte lorsque l'application est en cours d'exécution, il est donc nécessaire de s'assurer que le tas dispose de suffisamment d'espace pour que le programme puisse l'utiliser pendant le garbage collection. la collecte des déchets est terminée. Dans ce cas, un « échec du mode simultané » se produira et l’ensemble de l’application sera suspendue pour le garbage collection.
6. Démarrez le collecteur simultané : étant donné que la collecte simultanée est collectée pendant l'exécution de l'application, vous devez vous assurer qu'il y a suffisamment d'espace mémoire pour que le programme puisse l'utiliser avant la fin de la collecte, sinon une "échec du mode simultané" se produira. En définissant -XX:CMSInitiatingOccupancyFraction= spécifiez la quantité de tas restant pour commencer l'exécution de la collecte simultanée

4 Résumé
* Processeur série :
--Situation applicable : volume de données relativement. petit (environ 100 Mo) ; une application qui s'exécute sur un seul processeur et n'a aucune exigence en matière de temps de réponse.
--Inconvénients : ne peut être utilisé que pour de petites applications
* Processeur parallèle :
--Situations applicables : "exigences élevées en matière de débit", applications moyennes et grandes avec plusieurs processeurs et aucune exigence en matière de temps de réponse des applications Grandes applications. Exemples : traitement en arrière-plan, calcul scientifique.
--Inconvénient : le temps de réponse des applications peut être plus long
* Processeur simultané :
--Situation applicable : "exigences élevées en matière de temps de réponse", plusieurs processeurs, exigences élevées en matière de temps de réponse des applications Applications moyennes et grandes. Exemples : serveur Web/serveur d'applications, commutation de télécommunications, environnement de développement intégré.

3. Principes de base de GC
GC (Garbage Collection) est le garbage collector de JAVA/.NET.
Java a été développé à partir de C. Il a abandonné certaines choses lourdes et sujettes aux erreurs en C et a introduit le concept de compteurs. L'un d'eux est le mécanisme GC (C# emprunté à JAVA)
Les programmeurs sont sujets à des problèmes dans certains. Des endroits, un recyclage de mémoire oublié ou erroné peuvent entraîner une instabilité ou même un crash du programme ou du système. La fonction GC fournie par Java peut surveiller automatiquement si l'objet dépasse la portée pour atteindre l'objectif de recyclage automatique de la mémoire. un moyen de libérer la mémoire allouée. Montrez comment procéder. Par conséquent, la gestion de la mémoire de Java consiste en réalité à gérer des objets, y compris l'allocation et la libération d'objets.
Pour les programmeurs, allouez les objets à l'aide du mot-clé new ; lors de la libération d'un objet, attribuez simplement toutes les références à l'objet à null afin que le programme ne puisse plus accéder à l'objet. Nous appelons l'objet "inaccessible". responsable de récupérer l’espace mémoire de tous les objets « inaccessibles ».
Pour GC, lorsque le programmeur crée un objet, le GC commence à surveiller l'adresse, la taille et l'utilisation de l'objet. Habituellement, GC utilise un graphe orienté pour enregistrer et gérer tous les objets du tas. De cette manière, il est déterminé quels objets sont « accessibles » et quels objets sont « inaccessibles ». Lorsque le GC détermine que certains objets sont « inaccessibles », le GC est responsable de la récupération de ces espaces mémoire. Cependant, afin de garantir que GC puisse être implémenté sur différentes plates-formes, la spécification Java ne stipule pas strictement de nombreux comportements de GC. Par exemple, il n’existe pas de réglementation claire sur des questions importantes telles que le type d’algorithme de recyclage à utiliser et le moment où effectuer le recyclage. Par conséquent, les différents implémenteurs de JVM ont souvent des algorithmes d'implémentation différents. Cela apporte également beaucoup d'incertitude au développement des programmeurs Java. Cet article étudie plusieurs problématiques liées au travail de GC et s'efforce de réduire l'impact négatif de cette incertitude sur les programmes Java.

4. Division de génération GC
Le tas dans le modèle de mémoire JVM est divisé en deux grands blocs, l'un est la jeune génération et l'autre est l'ancienne génération

Une brève discussion sur quelques concepts de base sur le ramasse-miettes GC de Java

1) Dans Young Generation, il existe un espace appelé Eden Space, qui sert principalement à stocker de nouveaux objets. Il existe également deux Espaces Survivants (de, à). Leurs tailles sont toujours les mêmes. Ils servent à stocker. des déchets à chaque fois. Des objets qui survivent au recyclage.
2) En Ancienne Génération, il stocke principalement les objets mémoire à long cycle de vie dans les applications.
3) Dans le bloc Young Generation, le garbage collection utilise généralement l'algorithme de copie, qui est rapide. Lors de chaque GC, les objets survivants sont d'abord copiés d'Eden vers un SurvivorSpace. Lorsque l'Espace Survivant est plein, les objets vivants restants sont copiés directement vers OldGeneration. Par conséquent, après chaque GC, le bloc mémoire Eden sera effacé.
4) Dans le bloc Ancienne Génération, le garbage collection utilise généralement l'algorithme mark-compact, qui est plus lent mais réduit les besoins en mémoire.
5) La collecte des déchets est divisée en plusieurs niveaux. Le niveau 0 est une collecte des déchets complète (complète), qui recyclera les déchets du segment OLD ; le niveau 1 ou supérieur est une collecte des déchets partielle, qui recyclera uniquement les déchets de Young. Un dépassement de mémoire se produit généralement lorsqu'il n'y a toujours pas d'espace mémoire pour accueillir de nouveaux objets Java après la récupération de la mémoire du segment OLD ou Perm.

5. GC incrémentiel
Le GC incrémentiel est un GC qui est généralement implémenté par un ou un groupe de processus dans la JVM. Il occupe lui-même également l'espace du tas comme le programme utilisateur et s'exécute. Il consomme également du CPU.
Pendant que le processus GC est en cours d'exécution, l'application s'arrête. Par conséquent, lorsque GC s'exécute pendant une longue période, les utilisateurs peuvent ressentir une pause du programme Java. D'un autre côté, si GC s'exécute trop brièvement, le taux de recyclage des objets peut être trop faible, ce qui signifie qu'il reste encore de nombreux objets. doit être recyclé mais n'a pas été recyclé, prend toujours beaucoup de mémoire. Par conséquent, lors de la conception du GC, un compromis doit être fait entre le temps de pause et le taux de récupération. Une bonne implémentation du GC permet aux utilisateurs de définir les paramètres dont ils ont besoin. Par exemple, certains appareils avec une mémoire limitée sont très sensibles à l'utilisation de la mémoire. Ils espèrent que le GC pourra récupérer avec précision la mémoire, et il ne se soucie pas de la vitesse du programme. Les autres jeux en ligne en temps réel ne peuvent pas permettre de longues interruptions de programme.
Incremental GC utilise un certain algorithme de recyclage pour diviser une longue interruption en plusieurs petites interruptions. De cette manière, l'impact du GC sur les programmes utilisateur est réduit. Bien que le GC incrémentiel ne soit pas aussi efficace que le GC ordinaire en termes de performances globales, il peut réduire le temps de pause maximum du programme.
La JVM HotSpot fournie par Sun JDK prend en charge le GC incrémentiel. Le mode GC par défaut de HotSpot JVM consiste à ne pas utiliser de GC incrémentiel. Afin de démarrer le GC incrémentiel, nous devons ajouter le paramètre -Xincgc lors de l'exécution du programme Java.
Le GC incrémental HotSpot JVM est implémenté à l'aide de l'algorithme Train GC. Son idée de base est de regrouper (stratifier) ​​tous les objets du tas en fonction de leur création et de leur utilisation, et de regrouper les objets fréquemment utilisés et pertinents. , et les groupes sont continuellement ajustés au fur et à mesure de l'exécution du programme. Lorsque le GC s'exécute, il recycle toujours en premier les objets les plus anciens (rarement consultés récemment). Si l'ensemble du groupe est recyclable, le GC recyclera l'intégralité du groupe. De cette manière, chaque exécution de GC ne récupère qu'une certaine proportion d'objets inaccessibles pour assurer le bon fonctionnement du programme.

Pour plus d'articles sur certains concepts de base du garbage collector GC de Java, veuillez prêter attention au site Web PHP chinois !

É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