Ce que je vais partager avec vous ci-dessous est l'algorithme le plus basique de l'algorithme GC------l'algorithme de marquage/effacement. Si vous comprenez cet algorithme, les deux prochains seront un jeu d’enfant.
Tout d'abord, rappelons l'algorithme de recherche racine mentionné dans le chapitre précédent. Il peut résoudre le problème des objets à recycler, mais il ne peut évidemment pas supporter la lourde responsabilité du garbage collection, car nous sommes dans le programme ( le programme fait également référence à nous. Si vous souhaitez effectuer un garbage collection pendant le fonctionnement d'un programme JAVA exécuté sur la JVM, vous devez faire en sorte que le thread GC coopère avec les threads du programme afin que les déchets puissent être recyclés avec succès sans affecter le fonctionnement. du programme.
Afin d'atteindre cet objectif, l'algorithme mark/clear a vu le jour. Ce qu'il fait, c'est que lorsque l'espace mémoire disponible dans le tas est épuisé, il arrêtera tout le programme (également appelé arrêter le monde), puis effectuera deux tâches, la première est le marquage et la seconde l'élément est effacé.
LZ vous expliquera en détail ce que feront respectivement le marquage et le dégagement.
Marquage : le processus de marquage consiste en fait à parcourir toutes les racines GC, puis à marquer tous les objets accessibles par les racines GC comme des objets vivants.
Effacer : le processus de nettoyage traversera tous les objets du tas et effacera tous les objets non marqués.
En fait, ces deux étapes ne sont pas particulièrement compliquées et faciles à comprendre. LZ explique l'algorithme de marquage/effacement en termes simples. Lorsque le programme est en cours d'exécution, si la mémoire utilisable est épuisée, le thread GC sera déclenché et le programme sera suspendu, puis les objets survivants seront à nouveau marqués, et enfin tout effacer. objets non marqués dans le tas, puis laissez le programme reprendre son exécution.
Ci-dessous, LZ a créé un ensemble d'images pour vous permettre de décrire le processus ci-dessus. En combinaison avec les images, examinons ce processus de manière intuitive. La première image est la première image.
Cette image représente l'état de tous les objets pendant l'exécution du programme. Leurs bits d'indicateur sont tous à 0 (c'est-à-dire non marqués. La valeur par défaut ci-dessous est 0 pour non marqué, 1 pour (marqué), en supposant que l'espace mémoire effectif soit épuisé à ce moment-là, la JVM arrêtera l'exécution de l'application et démarrera le thread GC, puis démarrera le travail de marquage. Selon l'algorithme de recherche racine, après le marquage, le statut de l'objet est le suivant.
Comme vous pouvez le voir, selon l'algorithme de recherche racine, tous les objets accessibles depuis l'objet racine sont marqués comme objets vivants. À ce stade, la première étape de marquage est terminée. été achevé. Ensuite, la deuxième étape du nettoyage est effectuée. Une fois le nettoyage terminé, les objets restants et leur état sont comme indiqué dans la figure ci-dessous.
Comme vous pouvez le voir, les objets non marqués seront recyclés et effacés, tandis que les objets marqués resteront et le bit de marquage sera réinitialisé à 0. Inutile de dire qu'il suffit de réveiller le thread du programme arrêté et de laisser le programme continuer à s'exécuter.
En fait, ce processus n'est pas compliqué, on peut même dire qu'il est très simple, avez-vous raison ? Il y a cependant un point qui mérite d’être mentionné : pourquoi devons-nous arrêter le programme ?
Ce n'est en fait pas difficile à comprendre. LZ donnera l'exemple le plus simple. Supposons que notre programme et le thread GC fonctionnent ensemble.
Supposons que nous venions de marquer l'objet le plus à droite de l'image, appelons-le A pour le moment. En conséquence, un nouvel objet B est créé dans le programme à ce moment-là, et l'objet A peut atteindre l'objet B. . Cependant, puisque l'objet A a été marqué à ce moment, le bit de marquage de l'objet B est toujours à 0 car il a raté l'étape de marquage. Par conséquent, lorsque viendra le prochain tour pour effacer la phase, le nouvel objet B sera effacé durement. En conséquence, il n'est pas difficile d'imaginer le résultat du thread GC qui empêchera le programme de fonctionner correctement.
Le résultat ci-dessus est bien sûr inacceptable. Nous venons de créer un nouvel objet, et après un GC, il est soudainement devenu nul. Comment pouvons-nous jouer avec ?
Jusqu'à présent, l'algorithme mark/clear LZ a été introduit. Jetons un coup d'œil à ses défauts. En fait, après avoir compris le principe de son algorithme, ses défauts sont faciles à comprendre.
1. Tout d'abord, son inconvénient est que son efficacité est relativement faible (récursion et traversée complète des objets du tas), et lors de l'exécution du GC, l'application doit être arrêtée, ce qui entraînera une très mauvaise expérience utilisateur, notamment pour les applications interactives, c'est tout simplement inacceptable. Imaginez, si vous jouez sur un site Web et que le site est indisponible pendant cinq minutes par heure, joueriez-vous toujours ?
2. Le deuxième inconvénient principal est que la mémoire libre ainsi effacée est discontinue. Ce n'est pas difficile à comprendre. Nos objets morts apparaissent de manière aléatoire dans tous les coins de la mémoire. Maintenant, après les avoir effacés, la disposition de la mémoire apparaîtra naturellement. être en désordre. Pour faire face à cela, la JVM doit maintenir une liste de mémoire libre, ce qui représente une autre surcharge. De plus, lors de l'allocation d'objets tableau, il sera difficile de trouver un espace mémoire continu.
Après avoir constaté ses lacunes, certains amis singes ne pourront peut-être pas s'empêcher de vomir : « Donc cet algorithme est fondamentalement inutile, alors pourquoi LZ introduit-il une telle chose
Amis singes, ne vous inquiétez pas. , si un algorithme présente des lacunes, les experts feront naturellement de leur mieux pour l'améliorer. Les deux algorithmes que nous allons présenter ensuite sont tous deux optimisés sur la base de l'algorithme mark/clear. LZ partagera le contenu spécifique avec vous la prochaine fois.
Ceci met fin à ce partage. J'espère que vous gagnerez quelque chose en le lisant, 0.0.
Ce qui précède est le contenu de la gestion de la mémoire JVM------Raffinement de l'algorithme GC (cinq minutes pour que vous compreniez pleinement l'algorithme mark/clear. Pour plus de contenu connexe, veuillez faire attention au PHP). Site chinois (www.php.cn) !