Tutoriel recommandé : "Tutoriel vidéo JavaScript"
Récemment, j'ai vu des critiques d'entretiens, et beaucoup d'entre eux ont été invités à en parler par l'intervieweur JS garbage collection mécanisme, pour être honnête, l'intervieweur posera cette question, ce qui signifie qu'il a récemment vu des articles connexes sur le mécanisme JS garbage collection, et pour le bien du niveau B, il demandera en passant.
Récemment, j'ai vu un article étranger parlant du garbage collection JS. Je pensais que c'était expliqué clairement, alors je l'ai traduit, j'espère qu'il vous sera utile.
La gestion de la mémoire en JavaScript est effectuée automatiquement et de manière invisible. Nous créons des types primitifs, des objets, des fonctions... qui nécessitent tous de la mémoire.
Que se passe-t-il lorsque quelque chose n'est plus nécessaire ? Comment le moteur JavaScript le trouve-t-il et le nettoie-t-il ?
Le concept principal de la gestion de la mémoire en JavaScript est l'accessibilité. .
En termes simples, les valeurs « d'accessibilité » sont celles qui sont accessibles ou utilisables d'une manière ou d'une autre et dont le stockage en mémoire est garanti.
1. Il existe un ensemble de base de valeurs intrinsèquement accessibles qui ne peuvent pas être supprimées pour des raisons évidentes. Par exemple :
Variables et paramètres locaux de la fonction locale
Variables et paramètres d'autres fonctions sur la chaîne d'appel imbriquée actuelle
variables globales
et quelques autres, internes
ces valeurs appelées racine .
2. Une valeur est considérée comme accessible si la référence ou la chaîne de référence peut accéder à toute autre valeur à partir de la racine.
Par exemple, s'il y a un objet dans une variable locale et que cet objet a une propriété qui fait référence à un autre objet, alors l'objet est considéré comme accessible et ceux auxquels il fait référence sont également accessibles, verbeux. Exemples sont les suivants.
Il existe un processus en arrière-plan dans le moteur JavaScript appelé Garbage Collector, qui surveille tous les objets et supprime ceux qui sont inaccessibles.
Ce qui suit est l'exemple le plus simple :
// user 具有对象的引用 let user = { name: "John" };
La flèche ici représente une référence d'objet. La variable globale “user”
fait référence à l'objet {name:“John”}
(pour plus de simplicité, nous le nommons John). La propriété “name”
de John stocke un type primitif afin qu'il soit dessiné dans l'objet.
Si la valeur de user
est écrasée, la référence est perdue :
user = null;
Maintenant John devient inaccessible, il y a aucun moyen d'y accéder, aucune référence à celui-ci. Le garbage collector supprimera les données John et libérera la mémoire.
Supposons maintenant que nous copions la référence de user
à admin
:
// user具有对象的引用 let user = { name: "John" }; let admin = user;
Maintenant si On fait la même chose :
user = null;
L'objet est toujours accessible via la admin
variable globale, il est donc en mémoire. Si nous écrasons également admin
alors il peut être libéré.
Regardons maintenant un exemple plus complexe, l'objet familial :
function marry (man, woman) { woman.husban = man; man.wife = woman; return { father: man, mother: woman } } let family = marry({ name: "John" }, { name: "Ann" })
Fonctionmarry
"Marie" deux objets en fournissant des références l'un à l'autre et renvoie un nouvel objet contenant les deux objets.
Structure de mémoire résultante :
Jusqu'à présent, tous les objets sont accessibles.
Supprimons maintenant les deux références :
delete family.father; delete family.mother.husband;
Supprimer simplement l'une de ces deux références ne suffit pas car tous les objets sont toujours accessibles.
Mais si nous supprimons les deux, alors nous pouvons voir que John n'a plus de référence entrante :
Références de sortie ça n'a pas d'importance. Seul l'objet transmis rend l'objet accessible, par conséquent, John est désormais inaccessible et toutes les données inaccessibles seront supprimées de la mémoire.
Après le garbage collection :
Il est possible que l'intégralité de l'objet interconnecté devienne inaccessible et supprimé de la mémoire Supprimer dans .
L'objet source est le même que ci-dessus. Alors :
family = null;
L'image en mémoire devient :
Cet exemple illustre à quel point la notion d'accessibilité est importante.
De toute évidence, John et Ann sont toujours liés ensemble, tous deux ayant de nouvelles références. Mais cela ne suffit pas.
L'objet "famille" a été dissocié de la racine, il n'y a plus de références à celui-ci, donc tout le bloc ci-dessous devient inaccessible et sera supprimé.
L'algorithme de base de collecte des déchets est appelé "Mark-Sweep" et les étapes de "garbage collection" suivantes sont effectuées périodiquement :
L'éboueur récupère les racines et les "marques" (se souvenir).
Il accède ensuite et « marque » toutes les références d'eux.
Ensuite il accède aux objets marqués et marque leurs références. Tous les objets consultés sont mémorisés afin que le même objet ne soit pas accédé deux fois dans le futur.
et ainsi de suite jusqu'à ce qu'il y ait des références non visitées (accessibles depuis root).
Tous les objets sont supprimés sauf ceux marqués.
Par exemple, la structure de l'objet est la suivante :
On voit bien qu'il y a un "bloc inaccessible" sur la droite. Voyons maintenant comment le garbage collector « Mark and Sweep » le gère.
La première étape consiste à marquer les racines
puis à marquer leurs références
et références aux descendants :
Les objets désormais inaccessibles dans le processus sont considérés comme inaccessibles et seront supprimés :
C'est ainsi que fonctionne la collecte des déchets. Le moteur JavaScript applique de nombreuses optimisations pour le rendre plus rapide sans affecter l'exécution.
Quelques optimisations :
Recyclage générationnel - les objets sont divisés en deux groupes : « nouveaux objets » et « anciens objets ». De nombreux objets apparaissent, achèvent leur travail et se terminent rapidement, ils sont rapidement nettoyés. Ceux qui vivent assez longtemps deviennent « vieux » et sont rarement examinés.
Recyclage incrémental - S'il y a beaucoup d'objets et que nous essayons de parcourir et de marquer l'ensemble des objets à la fois, cela peut prendre un certain temps et dans l'exécution Il y aura un certain retard. Par conséquent, le moteur tente de diviser le garbage collection en plusieurs parties. Ensuite, chaque partie est exécutée séparément. Cela nécessite des marqueurs supplémentaires pour suivre les changements, il y a donc beaucoup de petits retards plutôt que de gros retards.
Collection des temps d'inactivité - Le garbage collector ne s'exécute que lorsque le processeur est inactif pour réduire l'impact possible sur l'exécution.
1) Demander ce qu'est une poubelle
De manière générale, les objets qui ne sont pas référencés sont garbage. Cela signifie être effacé. Il y a une exception. Si plusieurs références d'objet forment un anneau et se réfèrent les unes aux autres, mais que la racine ne peut pas y accéder, ces objets sont également des garbage et doivent être effacés.
2) Comment vérifier les déchets
Un algorithme est l'algorithme de marquage. Je veux également parler de différents algorithmes. Vous pouvez vous référer à ici.
Une explication plus approfondie V8 Journey : Garbage Collector
Pour plus de connaissances liées à la programmation, veuillez visiter : Introduction à la programmation ! !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!