Cet article est un article miroir de traduction automatique, veuillez cliquer ici pour accéder à l’article original.

Vue: 12807|Répondre: 0

[JavaSE] Acquérez une compréhension approfondie du mécanisme de collecte des déchets de Java

[Copié le lien]
Publié sur 04/12/2017 20:26:51 | | |
1. L’importance du mécanisme de recyclage des déchets  
Une caractéristique notable du langage Java est l’introduction d’un mécanisme de collecte des ordures, qui résout le problème de gestion de mémoire le plus problématique pour les programmeurs C++, de sorte que les programmeurs Java n’ont plus à prendre en compte la gestion de la mémoire lors de l’écriture de programmes. En raison du mécanisme de collecte des ordures, les objets en Java n’ont plus le concept de « portée », seule la référence de l’objet possède une « portée ».La collecte des déchets peut efficacement prévenir les fuites de mémoire et utiliser efficacement la mémoire inactive.

ps:内存泄露是指该内存空间使用完毕之后未回收,在不涉及复杂数据结构的一般情况下,Java 的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度,我们有时也将其称为“对象游离”。
2. Algorithmes dans les mécanismes de collecte des déchets  
La spécification du langage Java ne précise pas explicitement quel algorithme de collecte de déchets utiliser dans la JVM, mais tout algorithme de collecte des déchets doit généralement faire deux choses de base : (1) trouver des objets d’information inutiles ; (2) Récupérer l’espace mémoire occupé par des objets inutiles, afin que cet espace puisse être réutilisé par le programme.
1. Collecteur de comptage de références
1.1 Analyse des algorithmes

Le comptage des références est une stratégie précoce chez les éboueurs. Dans cette approche, il existe un compte de référence pour chaque instance d’objet dans le tas. Lorsqu’un objet est créé et que l’instance de l’objet est attribuée à une variable, le nombre de variables est fixé à 1. Lorsqu’une autre variable est attribuée comme référence à cet objet, le compte est ajouté de 1 (a = b, alors le compteur de l’instance d’objet référencée par b est +1), mais lorsqu’une référence à une instance d’objet a dépassé sa durée de vie ou est fixée à une nouvelle valeur, le compteur de référence de l’instance objet est soustrait de 1. Toute instance d’un objet avec un compteur de référence de 0 peut être collectée comme un déchet. Lorsqu’une instance d’objet est récupérée à la poubelle, le compteur de référence de toute instance d’objet qu’elle cite est de moins 1.
1.2 Avantages et inconvénients
Mérite:

Le collecteur de comptage de référence peut être exécuté très rapidement, intégré à l’exécution du programme. Il est avantageux pour les environnements en temps réel où les programmes ne doivent pas être interrompus pendant de longues périodes.
Défaut:

Les références circulaires ne peuvent pas être détectées. *Si l’objet parent fait référence à un objet enfant, l’objet enfant fait référence à son tour à l’objet parent. De cette façon, leur nombre de citations ne peut jamais être de 0.
1.3 L’algorithme de comptage des références ne peut pas résoudre le problème de référence circulaire, par exemple :
/** * Java学习交流QQ群:589809992 我们一起学Java! */public class Main {    public static void main(String[] args) {        MyObject object1 = new MyObject();        MyObject object2 = new MyObject();        object1.object = object2;        object2.object = object1;        object1 = null;        object2 = null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  
Les deux dernières phrases attribuent object1 et object2 à null, ce qui signifie que les objets pointés par objet1 et objet2 ne peuvent plus être consultés, mais comme ils se réfèrent l’un à l’autre, leurs compteurs de référence ne sont pas 0, donc le collecteur ne les recyclera jamais.
2. Collecteur de traçage ou algorithme de marquage et balayage
2.1 Algorithme de recherche root


L’algorithme de recherche de racines est introduit à partir de la théorie des graphes en mathématiques discrètes ; le programme considère toutes les relations de référence comme un graphe, en partant d’un nœud GC ROOT, en cherchant le nœud de référence correspondant, après avoir trouvé ce nœud, en continuant à chercher le nœud de référence de ce nœud, et lorsque tous les nœuds de référence sont recherchés, les nœuds restants sont considérés comme des nœuds non référencés, c’est-à-dire des nœuds inutiles.
Java qui peut être utilisé comme racine GC
1. Objets référencés dans la pile de machines virtuelles (table des variables locales)
2. L’objet référencé par l’attribut statique dans la zone de la méthode
3. L’objet référencé par la constante dans l’aire de la méthode
4. Objets référencés dans la pile de méthodes locale (objets natifs)
2.2 Schéma de l’algorithme de traçage

2.3 Analyse de l’algorithme de suppression des marqueurs

L’algorithme de purge des tags scanne la collection root, marque les objets survivants, puis parcourt tout l’espace à la recherche d’objets non étiquetés à recycler, comme montré dans la figure ci-dessus. L’algorithme de purge des balises n’a pas besoin de déplacer les objets, et ne traite que les objets non survivants, ce qui est extrêmement efficace lorsqu’il y a beaucoup d’objets survivants, mais comme l’algorithme de purge des balises recycle directement les objets non survivants, cela provoque une fragmentation de la mémoire.
3. Algorithme de compactage ou algorithme de finition d’étiquetage


L’algorithme de fin de balises utilise la même méthode que l’algorithme de nettoyage des balises pour étiqueter les objets, mais il diffère lors du purge : après avoir récupéré l’espace occupé par les objets non survivants, il déplace tous les objets survivants dans l’espace libre à l’extrémité gauche et met à jour le pointeur correspondant. L’algorithme tag-finish est basé sur l’algorithme de purge des tags et déplace les objets, il est donc plus coûteux, mais il résout le problème de la fragmentation de la mémoire. Dans la mise en œuvre des collecteurs basés sur l’algorithme de compactage, des handles et des tables de handles sont généralement ajoutées.
4. Algorithme de copie (collecteur de compactage)


L’algorithme est proposé pour compenser la surcharge de la poignée et résoudre la collecte des déchets du tas. Lorsque l’objet est plein, le ramasser des déchets basé sur l’algorithme de copie scanne l’objet actif à partir de l’ensemble racine, et copie chaque objet actif dans la face libre (de sorte qu’il n’y ait pas de trous libres entre la mémoire occupée par l’objet actif), de sorte que la surface libre devient la face de l’objet, la face d’objet d’origine devient la face libre, et le programme alloue de la mémoire dans la nouvelle face de l’objet. Un garbage collection typique basé sur l’algorithme de coping est l’algorithme stop-and-copy, qui divise le tas en faces d’objet et faces de surface libre, et le programme met en pause l’exécution lors du passage entre faces d’objet et faces de surface libre.
5. Collectionneur générationnel


La stratégie générationnelle de recyclage des déchets repose sur le fait queLe cycle de vie des différents objets est différent。 Ainsi, les objets ayant des cycles de vie différents peuvent adopter différents algorithmes de recyclage pour améliorer l’efficacité du recyclage.
Jeune génération
1. Tous les nouveaux objets générés sont placés d’abord dans la jeune génération. L’objectif de la jeune génération est de collecter ces objets au cycle de vie court le plus rapidement possible.

2. La mémoire de la nouvelle génération est divisée en une région d’Éden et deux zones survivants (survivant0, survivant1) selon le ratio de 8:1:1. Une zone Éden, deux zones Survivants (en général). La plupart des objets apparaissent dans la zone d’Eden. Lorsque la zone survivant0 est également pleine, la zone Eden et la zone survivant 0 sont copiées dans une autre zone survivant1, puis les zones Éden et Survivant0 sont vidées, puis la zone survivant0 est vide, et ensuite la zone survivant0 et la zone survivant1 sont échangées. C’est-à-dire garder la zone survivant1 vide, et ainsi de suite.

3. Lorsque la zone survivant 1 ne suffit pas à stocker les objets survivants d’Eden et survivor0, les objets survivants sont stockés directement à l’ancienne ère. Si la vieillesse est aussi pleine, cela déclenchera une grande génération de la génération, c’est-à-dire que la nouvelle génération et l’ancienne génération seront recyclées

4. La GC de la nouvelle génération est également appelée GC Mineure, et la fréquence de la GC Mineure est relativement élevée (elle n’est pas nécessairement déclenchée lorsque la zone Eden est pleine)
Ancienne génération

1. Les objets encore vivants après avoir expérimenté le recyclage des déchets N chez la jeune génération seront placés dans la génération plus âgée. Par conséquent, on peut considérer que l’ancienne génération est stockée dans certains objets ayant un long cycle de vie.

2. La mémoire est également beaucoup plus grande que celle de la nouvelle génération (le ratio approximatif est de 1:2), lorsque la mémoire de l’âge avancé est pleine, la GC majeure est déclenchée, c’est-à-dire la GC complète, la fréquence de la GC complète est relativement faible, le temps de survie de l’objet de vieillesse est relativement long, et le taux de survie est élevé.
Génération permanente
Utilisé pour stocker des fichiers statiques, tels que des classes Java, des méthodes, etc. Les générations persistantes n’ont pas d’impact significatif sur la collecte des ordures, mais certaines applications peuvent générer ou appeler dynamiquement certaines classes, comme Hibernate, etc., et dans ce cas, un espace de génération persistant relativement grand doit être configuré pour stocker ces nouvelles classes pendant l’exécution.
3. GC (Rambeau-ordures)Collectionneurs utilisés par la nouvelle génération : Serial, PraNew, Parallel Scavenge
Collectionneurs utilisés par les collectionneurs Old Age : Serial Old, Parallel Old, CMS

Collecteur en série (algorithme de réplication)
La nouvelle génération de collecteurs à filetage unique, le marquage et le nettoyage sont à simple filet, avec l’avantage d’être simples et efficaces.
Collecteur ancien en série (algorithme d’étiquette et finition)
Old Age Single Thread Collector, version Old Age du Serial Collector.
Collecteur ParNew (algorithme stop-copy)
Le collecteur de nouvelle génération peut être considéré comme une version multi-thread du collecteur Série, qui offre de meilleures performances que le Serial dans un environnement CPU multi-cœur.
Collecteur de récupération parallèle (algorithme stop-copy)
Collecteurs parallèles pour un haut débit et une utilisation efficace du processeur. Le débit est généralement de 99 %, et le débit = temps de thread utilisateur / (temps thread utilisateur + temps thread GC). Il convient à des scénarios tels que des applications en arrière-plan qui ne nécessitent pas d’interactions élevées en conséquence.
Collecteur ancien parallèle (algorithme stop-copy)
Une version plus ancienne du collecteur Parallel Scavenge, un collecteur parallèle, avec priorité de débit
Collecteur CMS (Concurrent Mark Sweep) (Algorithme Mark-Clean)
Forte concurrence, pauses faibles, recherche du temps de pause de récupération GC le plus court, utilisation élevée du CPU, temps de réponse rapide, temps de pause court, et CPU multi-cœur poursuivant un temps de réponse élevé
4. Le mécanisme de mise en œuvre de la GCPuisque l’objet a été traité sur différentes générations, la zone et le moment de la collecte des déchets sont également différents. Il existe deux types de GC : GC Récupération et GC complet.
GC de récupération
Normalement, lorsqu’un nouvel objet est généré et ne demande pas d’espace dans Eden, le GC Scavenge est déclenché, ce qui GC la zone Eden, élimine les objets non survivants et déplace les objets survivants vers la zone Survivant. Ensuite, réglez les deux zones de Survivor. La GC est ainsi réalisée dans la zone Eden de la jeune génération et n’affecte pas la génération plus âgée. Comme la plupart des objets commencent dans la zone de l’Éden, et que la zone de l’Éden n’est pas beaucoup allouée, la GC de la zone de l’Éden est fréquemment effectuée. Il est donc généralement nécessaire d’utiliser ici des algorithmes rapides et efficaces pour rendre Eden libre le plus rapidement possible.
Classement général complet
Organisez toute la pile, y compris les jeunes, les titulaires et les titulaires permanents. La Full GC est plus lente que la GC Scavenge car elle nécessite de recycler tout le tas, donc le nombre de Full GC devrait être réduit autant que possible. Une grande partie du processus de réglage de la JVM consiste à l’accord du FullGC. La GC complète peut être causée par les raisons suivantes :
1. La titularisation est rédigée en totalité
2. La permanente s’écrit en intégralité  
3. System.gc() s’affiche comme un appel  
4. La stratégie d’allocation de domaine du tas change dynamiquement après la dernière GC
5. Java avec GC aura également des problèmes de fuite de mémoire1. L’utilisation de classes de collection statiques telles que HashMap, Vector, etc. est la plus sujette à la fuite de mémoire, et le cycle de vie de ces variables statiques est le même que celui de l’application, et tous les objets ne peuvent pas être libérés, car ils seront toujours appliqués par Vector et d’autres.
Vecteur statique v = nouveau vecteur() ; pour (int i = 1 ; i<100 ; i++) { Objet o = nouvel Objet() ;     v.add(o) ;     o = nul ; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  
Dans cet exemple, il existe une référence v pour l’objet Vector et une référence o pour l’objet objet dans la pile de codes. Dans la boucle For, nous continuons à générer de nouveaux objets, puis à les ajouter à l’objet Vector, et ensuite à annuler la référence o. La question est : lorsque la référence o est annulée, si GC apparaît, l’objet objet que nous avons créé peut-il être recyclé par GC ? La réponse est non. Parce que lorsque GC suit les références dans la pile de code, il trouve v références, et si vous continuez à suivre, vous constaterez qu’il y a des références à des objets Objet dans l’espace mémoire pointés par v références. Cela signifie que même si la référence o a été vidée, il existe encore d’autres références à l’objet objet accessibles, donc le GC ne peut pas les libérer. Si, après cette boucle, l’objet objet n’a aucun effet sur le programme, alors on suppose que le programme Java a une fuite de mémoire.
2. Diverses connexions, connexions de base de données, connexions réseau, connexions d’entrée, etc. n’affichent pas l’appel proche de la clôture, et ne sont pas recyclées par GC, ce qui entraîne une fuite de mémoire.
3. L’utilisation d’écouteurs peut également provoquer une fuite de mémoire lorsque l’écouteur n’est pas supprimé lors de la libération de l’objet.




Précédent:Les débutants jouent un peu de technologie noire en CSS
Prochain:Méfiez-vous du virus de Troie logiciel Wanke Cloud Snap !
Démenti:
Tous les logiciels, supports de programmation ou articles publiés par Code Farmer Network sont uniquement destinés à l’apprentissage et à la recherche ; Le contenu ci-dessus ne doit pas être utilisé à des fins commerciales ou illégales, sinon les utilisateurs assumeront toutes les conséquences. Les informations sur ce site proviennent d’Internet, et les litiges de droits d’auteur n’ont rien à voir avec ce site. Vous devez supprimer complètement le contenu ci-dessus de votre ordinateur dans les 24 heures suivant le téléchargement. Si vous aimez le programme, merci de soutenir un logiciel authentique, d’acheter l’immatriculation et d’obtenir de meilleurs services authentiques. En cas d’infraction, veuillez nous contacter par e-mail.

Mail To:help@itsvse.com