Introduction
Quel est l'algorithme ultime ?
En fait, c'est l'algorithme utilisé par la JVM actuelle, et ce n'est pas le véritable ultime. Peut-être que quelques années plus tard, il y aura un nouvel algorithme ultime, et il y en aura certainement un, car LZ croit dans les capacités des personnes avancées.
Alors, comment l'algorithme de collecte générationnelle gère-t-il le GC ?
Classification des objets
Comme mentionné dans le chapitre précédent, l'algorithme de collecte générationnelle est basé sur les différentes caractéristiques des objets et utilise des algorithmes appropriés. Aucun nouvel algorithme n'est réellement produit. Plutôt que de dire que l’algorithme de collecte générationnelle est le quatrième algorithme, il vaut mieux dire qu’il s’agit d’une application pratique des trois premiers algorithmes.
Tout d'abord, discutons des différentes caractéristiques des objets. Ensuite, LZ et tout le monde choisiront les algorithmes GC pour ces objets.
Les objets en mémoire peuvent être grossièrement divisés en trois types en fonction de la durée de leur cycle de vie. Les noms suivants sont tous les noms personnels de LZ.
1. Les objets qui meurent jeunes : les objets qui naissent et disparaissent. En termes simples, ce sont des objets qui mourront avant de pouvoir vivre longtemps.
Exemples : variables locales d'une certaine méthode, variables temporaires dans une boucle, etc.
2. Objets immortels âgés : Ce type d'objet vit généralement plus longtemps et est encore en vie à un âge très avancé. Mais en dernière analyse, les objets immortels âgés sont presque certains de mourir tôt ou tard, mais seulement presque.
Exemples : objets de cache, objets de connexion à une base de données, objets singleton (mode singleton), etc.
3. Objets immortels : De tels objets sont généralement presque immortels une fois nés. Ils seront presque toujours immortels. Rappelez-vous qu'ils sont simplement presque immortels.
Exemples : objets dans le pool String (mode flyweight), informations de classe chargées, etc.
La zone mémoire correspondant à l'objet
Vous souvenez-vous encore de la division de la mémoire par la JVM lorsque nous avons introduit la gestion de la mémoire plus tôt ?
Nous mappons les trois objets ci-dessus à la zone mémoire, c'est-à-dire que les objets prématurés et les objets immortels sont dans le tas JAVA, et les objets immortels sont dans la zone méthode.
Nous avons déjà dit dans le chapitre précédent que pour le tas JAVA, la spécification JVM exige que GC soit implémenté. Par conséquent, pour les objets prématurés et les objets immortels, la mort est presque une issue inévitable, mais elle n'est que presque inévitable. Certains objets survivront jusqu'à la fin de l'application. Cependant, la spécification JVM n'exige pas GC dans la zone méthode, donc en supposant qu'une implémentation JVM n'implémente pas GC dans la zone méthode, alors l'objet immortel est un objet véritablement immortel.
Le cycle de vie des objets immortels étant trop long, l'algorithme de collecte générationnelle est conçu pour le tas JAVA, c'est-à-dire pour les objets prématurés et les anciens objets immortels.
Recyclage d'objets du tas JAVA (objets jeunes et vieux objets immortels)
Avec l'analyse ci-dessus, examinons comment l'algorithme de collecte générationnelle gère le recyclage de la mémoire du tas JAVA, c'est-à-dire les objets prématurés Recyclage d'objets et d'objets immortels.
Objets abandonnés : ce type d'objet va et vient et a une courte durée de survie. Vous souvenez-vous encore des conditions requises pour utiliser l'algorithme de réplication ? Autrement dit, le taux de survie des objets ne peut pas être trop élevé, les objets prématurés sont donc les plus adaptés à l'utilisation de l'algorithme de réplication.
Petite question : Que dois-je faire si 50 % de la mémoire est gaspillée ?
Réponse : Le taux de survie des objets prématurés étant généralement faible, il n'est pas nécessaire d'utiliser 50 % de la mémoire comme libre. Généralement, deux 10 % de la mémoire sont utilisés comme plage libre et active, et l'autre. 80 % de la mémoire est utilisée pour allouer de la mémoire aux nouveaux objets. Une fois qu'un GC se produit, 10 % de la plage active et les 80 % restants des objets survivants sont transférés vers 10 % de la plage libre. Ensuite, les 90 % de la mémoire précédente sont libérés, et ainsi de suite.
Afin de vous permettre de voir plus clairement ce processus GC, LZ propose le schéma suivant.
L'image marque l'état de la mémoire de chacune des trois zones à chaque étape. Je pense qu'en regardant l'image, son processus GC n'est pas difficile à comprendre.
Cependant, il y a deux points que LZ doit mentionner. Le premier point est qu'en utilisant cette méthode, nous ne gaspillons que 10 % de la mémoire. Ceci est acceptable car nous obtenons une disposition soignée de la mémoire et de la vitesse du GC. Le deuxième point est que le principe de cette stratégie est que la mémoire occupée par chaque objet survivant ne peut pas dépasser cette taille de 10 %. Une fois dépassée, les objets supplémentaires ne seront pas copiés.
Afin de résoudre la situation inattendue ci-dessus, c'est-à-dire lorsque la mémoire occupée par les objets survivants est trop grande, les experts divisent le tas JAVA en deux parties à traiter. Les trois zones ci-dessus constituent la première partie, appelée la nouvelle. génération ou jeune génération. La partie restante, dédiée au stockage des objets anciens et immortels, est appelée l'ancienne génération.
N'est-ce pas un nom très approprié ? Voyons comment gérer les vieux objets immortels.
Anciens objets immortels : Le taux de survie de ce type d'objets est très élevé car la plupart d'entre eux sont transférés de la nouvelle génération. Tout comme les gens, après avoir vécu longtemps, ils deviennent immortels.
Normalement, lorsque les deux situations suivantes se produisent, l'objet sera transféré de la zone nouvelle génération vers l'ancienne zone.
1. Chaque objet de la nouvelle génération aura un âge lorsque l'âge de ces objets atteint un certain niveau (l'âge est le nombre de GC qui ont survécu, si l'objet survit à chaque GC, l'âge sera augmenté. par 1) , il sera transféré à l'ancienne génération, et la valeur d'âge de ce transfert à l'ancienne génération peut généralement être définie dans la JVM.
2. Lorsque la mémoire occupée par les objets survivants de la nouvelle génération dépasse 10%, les objets excédentaires seront placés dans l'ancienne génération. A l'heure actuelle, l'ancienne génération est « l'entrepôt de secours » de la nouvelle génération.
Sur la base des caractéristiques de l'objet ancien et immortel, il n'est évidemment plus adapté d'utiliser l'algorithme de réplication car son taux de survie est trop élevé, et n'oubliez pas que si l'ancienne génération utilise à nouveau l'algorithme de réplication, il n'aura pas d'entrepôt de secours. Par conséquent, généralement, seuls les algorithmes de marquage/organisation ou de marquage/effacement peuvent être utilisés pour les anciens objets immortels.
Recyclage d'objets dans la zone méthode (objets immortels)
Les deux situations ci-dessus ont résolu la plupart des problèmes du GC, car le tas JAVA est l'objectif principal du GC, et ce qui précède a a également été inclus. L'intégralité du contenu de l'algorithme de collecte générationnelle a été couverte et le recyclage ultérieur des objets immortels ne fait plus partie de l'algorithme de collecte générationnelle.
Les objets immortels existent dans la zone de méthode. Dans notre machine virtuelle hotspot couramment utilisée (JVM par défaut du JDK), la zone de méthode est aussi affectueusement appelée génération permanente, n'est-ce pas ?
En fait, il y a bien longtemps, il n’y avait pas de génération permanente. À cette époque, la génération permanente et l'ancienne génération étaient stockées ensemble, qui contenaient des informations d'instance et des informations de classe des classes JAVA. Cependant, on a découvert plus tard que le déchargement des informations de classe se produisait rarement, les deux ont donc été séparés. Heureusement, cela améliore considérablement les performances. La génération permanente était donc divisée.
Le GC dans cette partie de la zone utilise une méthode similaire à l'ancienne génération. Puisqu'il n'y a pas d'"entrepôt de sauvegarde", les deux ne peuvent utiliser que les algorithmes de marquage/effacement et de marquage/organisation.
Moment du recyclage
Lorsque la JVM effectue GC, les trois zones mémoire ci-dessus ne sont pas recyclées ensemble à chaque fois. La plupart du temps, le recyclage fait référence à la nouvelle génération. Par conséquent, les GC sont divisés en deux types selon la zone de recyclage, l’un est le GC ordinaire (GC mineur) et l’autre est le GC global (GC majeur ou Full GC). Les domaines qu’ils ciblent sont les suivants.
GC normal (GC mineur) : GC uniquement pour la zone nouvelle génération.
GC Global (GC majeur ou Full GC) : GC pour l'ancienne génération, accompagné occasionnellement de GC pour la nouvelle génération et de GC pour la génération permanente.
Étant donné que l'effet GC de l'ancienne génération et de la génération permanente est relativement faible et que l'utilisation de la mémoire des deux augmente lentement, il faut généralement plusieurs GC ordinaires pour déclencher un GC global.
Conclusion
Ce qui précède est la gestion de la mémoire JVM ------ Explication détaillée de l'algorithme GC (cinq minutes pour vous apprendre l'algorithme ultime --- collection générationnelle algorithme) Contenu, veuillez faire attention au site Web PHP chinois (www.php.cn) pour plus de contenu connexe !