Pourquoi JavaScript nettoie-t-il tout seul, mais devons-nous quand même comprendre comment ça marche ?
\n\nLorsque vous écrivez en JavaScript, vous pensez rarement à ce qui arrive aux variables après qu'elles soient sorties de la portée. Contrairement au C ou au C++, où vous devez manuellement appeler free() ou delete, JavaScript se charge du sale boulot de nettoyage de la mémoire. C'est pratique — jusqu'au moment où votre application commence à « ralentir », à consommer des gigaoctets de RAM ou à planter soudainement avec une erreur Out of Memory.
Ça vous parle ? Alors découvrons comment fonctionne réellement la gestion de la mémoire en JavaScript et ce qu'est le garbage collector JavaScript. Spoiler : ce n'est pas de la magie, mais un algorithme strict qu'il faut (et qu'on peut) prendre en compte lors de l'écriture du code.
\n\nComment JavaScript stocke les données : la pile et le tas
\n\nAvant de parler du garbage collection, il faut comprendre où vivent les données. En JavaScript, il y a deux espaces de stockage principaux :
\n\n- \n
- La pile (Stack) — une mémoire rapide mais limitée. Elle stocke les primitives (nombres, chaînes de caractères, valeurs booléennes) et les références aux objets. Chaque appel de fonction crée un nouveau cadre dans la pile. \n
- Le tas (Heap) — une zone mémoire non structurée où vivent les objets, les tableaux, les fonctions et les fermetures. C'est ici que se déroule la principale lutte pour la mémoire. \n
Lorsque vous créez un objet :
\n\nlet user = { name: 'Иван', age: 30 };\n\n\nLa référence user va dans la pile, et l'objet lui-même { name: 'Иван', age: 30 } va dans le tas. Tant qu'il y a au moins une référence sur l'objet, il reste vivant. Dès qu'il n'y a plus de références, l'objet devient un « déchet ».
Le garbage collector en JavaScript : le héros principal
\n\nLe garbage collector en JavaScript (GC) est un processus en arrière-plan qui vérifie périodiquement le tas et supprime les objets inaccessibles. Ça semble simple, mais en pratique c'est un compromis complexe entre la vitesse de nettoyage et les performances de votre code.
\n\nL'algorithme Mark-and-Sweep (Marquage et balayage)
\n\nLes moteurs modernes (V8 dans Chrome, SpiderMonkey dans Firefox) utilisent l'algorithme Mark-and-Sweep. Il fonctionne en deux étapes :
\n\n- \n
- Mark (Marquage) : Le GC commence par les objets racines (l'objet global, les fonctions en cours, les variables locales). Il parcourt toutes les références à partir des racines et marque chaque objet accessible. \n
- Sweep (Balayage) : Tous les objets non marqués sont considérés comme des déchets et sont supprimés. La mémoire est libérée. \n
Un exemple simple :
\n\nlet a = { data: 'A' };\nlet b = { data: 'B' };\na.ref = b; // a référence b\nb.ref = a; // b référence a\n\n// Nous avons maintenant une référence circulaire\na = null; // a ne pointe plus vers l'objet\nb = null; // b ne pointe plus vers l'objet\n\n\nAvant (avant l'arrivée de Mark-and-Sweep), de telles références circulaires entraînaient des fuites mémoire. Mais le GC moderne comprend : si les deux objets sont inaccessibles depuis la racine, ce sont des déchets, même s'ils se référencent mutuellement.
\n\nLes générations d'objets : jeunes et vieux
\n\nLa plupart des objets vivent peu de temps. Par exemple, les variables temporaires à l'intérieur d'une fonction. C'est pourquoi V8 divise le tas en générations :
\n\n- \n
- Young Generation (Jeune génération) : les nouveaux objets. Le nettoyage y est fréquent et rapide (Scavenge — un algorithme qui copie les objets vivants dans une autre zone). \n
- Old Generation (Vieille génération) : les objets qui ont survécu à plusieurs nettoyages. Ils sont vérifiés moins souvent, mais le processus prend plus de temps. \n
Cette approche permet de ne pas « figer » la page pendant une vérification complète de tout le tas.
\n\nLes fuites mémoire en JavaScript : comment les provoquer (et ne pas le faire)
\n\nMême avec un garbage collector intelligent, on peut créer une situation où la mémoire n'est pas libérée. Voici les causes les plus fréquentes de fui