| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Memory_management | [Back] [Original] |
Get to know MDN better
Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.
Les langages de bas niveau, tels que C, possdent des primitives permettant de grer la mmoire : malloc() et free() par exemple. En revanche, lorsqu'on utilise JavaScript, la mmoire est alloue lors de la cration des objets puis libre automatiquement lorsque ceux-ci ne sont plus utiliss. Cette libration automatique est appele garbage collection en anglais ou ramasse-miettes. Le fait que ce processus soit automatique est souvent source de confusion et donne parfois l'impression que JavaScript (ou d'autres langages de haut niveau) ne permet pas de grer la mmoire : nous allons voir que ce n'est pas le cas.
Quel que soit le langage de programmation, le cycle de vie de la mmoire ressemblera :
Le deuxime point est explicite, au niveau du code, pour tous les langages de programmation. Le premier et le troisime points sont explicites pour les langages de bas niveau mais souvent implicites pour les langages de haut niveau tels que JavaScript.
Afin de simplifier l'criture de code, JavaScript alloue la mmoire lors de la dclaration des variables :
// alloue de la mmoire pour un nombre
var n = 123;
// alloue de la mmoire pour une chane de caractres
var s = "azerty";
// alloue de la mmoire pour un objet et les valeurs qu'il contient
var o = {
a: 1,
b: null,
};
// alloue de la mmoire pour un tableau et les valeurs qu'il contient
var a = [1, null, "abra"];
// alloue de la mmoire pour une fonction
// une fonction est un objet qui peut tre appel
function f(a) {
return a + 2;
}
// les expressions de fonction allouent aussi de la mmoire
unElement.addEventListener(
"click",
function () {
unElement.style.backgroundColor = "blue";
},
false,
);
Certains appels de fonctions entranent l'allocation mmoire d'un objet.
// Alloue la mmoire pour un objet date
var d = new Date();
// Alloue de la mmoire pour un objet reprsentant un lment du DOM
var e = document.createElement("div");
Certaines mthodes allouent de la mmoire pour des nouveaux objets ou de nouvelles valeurs.
var s = "azerty";
var s2 = s.substr(0, 3); // s2 est une nouvelle chane de caractres
// Les chanes tant immuables, JavaScript peut choisir
// de ne pas allouer de mmoire mais seulement
// de stocker l'intervalle [0, 3].
var a = ["ouais ouais", "nan nan"];
var a2 = ["gnration", "nan nan"];
var a3 = a.concat(a2);
// nouveau tableau de 4 lments
// (rsultat de la concatnation de a et a2)
Utiliser des variables revient lire et crire la mmoire alloue. Cela peut tre effectu lorsqu'on lit ou modifie la valeur d'une variable ou d'une proprit d'un objet ou encore lorsqu'on passe un argument une fonction.
La plupart des problmes concernant la gestion de la mmoire surviennent cet endroit. Le plus difficile est de savoir quand la mmoire alloue n'est plus utilise. Pour les langages bas niveau , il faut donc que le dveloppeur dtermine quelle partie de la mmoire n'est plus utilise tel endroit du code et la libre.
Les interprteurs des langages de haut niveau intgrent un composant logiciel, appel ramasse-miettes qui a pour but de surveiller l'utilisation de la mmoire afin de dterminer quand une partie de la mmoire alloue n'est plus utilise afin de la librer automatiquement. Ce procd ne peut tre qu'une approximation car savoir si tel ou tel fragment de mmoire est ncessaire est un problme indcidable (autrement dit, ce problme ne peut tre rsolu par un algorithme).
Comme on vient de le voir, savoir si de la mmoire peut tre libre demeure un problme indcidable. Les ramasses-miettes ne sont donc que des solutions restreintes pour ce problme. La section qui suit dtaille les notions importantes pour comprendre ce mcanisme, ainsi que ses limitations.
Le concept principal utilis par les algorithmes de ramasse-miettes est celui de rfrence. Dans ce contexte, un objet en rfrence un autre lorsqu'il a accs lui (implicitement ou explicitement). Ainsi, un objet JavaScript rfrencera son prototype (rfrence implicite) et ses proprits (rfrence explicite).
Dans ce contexte, la notion d'objet s'tend et dpasse celle utilise pour dcrire les objets JavaScript, elle contiendra notamment les portes de fonctions (ou la porte globale).
L'algorithme le plus simple consiste faire l'quivalence entre un objet n'est plus ncessaire et un objet n'a pas d'objet le rfrenant . Ainsi un objet peut tre ramass par le ramasse-miettes quand il n'y a plus de rfrences pointant vers lui.
var o = {
a: {
b: 2,
},
};
// 2 objets sont crs. L'un est rfrenc par l'autre en tant que proprit.
// L'autre est rfrenc car assign la variable 'o'.
// Aucun des deux ne peut tre ramass par le ramasse-miettes.
var o2 = o; // la variable 'o2' est le deuxime lment qui
// rfrence l'objet o
o = 1; // dsormais, l'objet qui tait dans 'o' possde
// une seule rfrence de o2 vers lui
var oa = o2.a; // rfrence la proprit 'a' de l'objet
// cet objet a donc 2 rfrences : une
// par une proprit, l'autre par la variable 'oa'
o2 = "yo"; // L'objet 'o' ne possde plus de rfrences vers lui
// Il peut tre ramass.
// Cependant sa proprit 'a' est toujours rfrenc.
// La mmoire ne peut donc pas tre libre.
oa = null; // la proprit 'a' ne possde plus de rfrences
// vers elle. L'objet peut tre ramass et la mmoire
// libre.
Cet algorithme est limit car il ne peut pas grer les cycles (exemple : A rfrence B et B rfrence A, ce qui forme un cycle). Avec les cycles, des objets pourraient trs bien ne plus tre ncessaires et cependant il serait impossible de les ramasser pour librer la mmoire en utilisant l'algorithme prcdent car chaque objet serait rfrenc au moins une fois et aucun ne pourrait tre ramass . Les rfrences circulaires peuvent parfois entraner des fuites mmoire.
function f() {
var o = {};
var o2 = {};
o.a = o2; // o rfrence o2
o2.a = o; // o2 rfrence o
return "azerty";
}
f();
Les navigateurs Internet Explorer 6 et 7 utilisent cet algorithme pour grer les objets du DOM. Certains codes peuvent donc entraner des fuites de mmoires, en voici un exemple :
var div;
window.onload = function () {
div = document.getElementById("monElementDiv");
div.referenceCirculaire = div;
div.desDonnees = new Array(10000).join("*");
};
Dans cet exemple, l'lment du DOM monElementDiv possde une rfrence circulaire vers lui-mme via la proprit referenceCirculaire. Si la proprit n'est pas retire ou modifie de faon explicite, un ramasse-miettes qui compte les rfrences aura toujours au moins une rfrence compte, ce qui gardera l'lment DOM en mmoire et ce mme s'il a t retir de l'arbre du DOM. Si l'lment du DOM contient beaucoup de donnes (ce qui est illustr ici avec la proprits desDonnes), la mmoire consomme par ces donnes ne sera jamais libre.
Cet algorithme rduit la dfinition un objet n'est plus ncessaire un objet ne peut tre atteint .
L'utilisation de cet algorithme implique de savoir quels sont les objets racines (en JavaScript, la racine est l'objet global). De faon priodique, le ramasse-miettes commencera par ces racines, listera tous les objets rfrencs par ces racines, puis les objets rfrencs par eux etc. Le ramasse-miettes pourra ainsi construire une liste de tous les objets accessibles et collecter ceux qui ne sont plus accessibles.
Cet algorithme est meilleur que le prcdent car la proposition un objet possde 0 rfrence implique un objet ne peut tre atteint . En revanche, la rciproque n'est pas vraie comme nous avons pu le voir avec les cycles.
En 2012, l'ensemble des navigateurs web modernes disposent d'un ramasse-miettes implmentant cet algorithme mark-and-sweep. L'ensemble des amliorations apportes dans ce domaine de JavaScript reprsentent des amliorations bases sur cet algorithme, ce ne sont pas de nouveaux algorithmes ou une nouvelle dfinition pour les objets supprimer.
Dans l'exemple ci-dessus, aprs le retour de la fonction, les deux objets ne sont plus rfrencs par quelque chose d'accessible depuis l'objet global. L'algorithme les marquera donc comme non-accessibles .
On pourrait parfois avoir envie de dcider quand librer la mmoire. En 2019, il n'est pas possible de dclencher le ramasse miettes en JavaScript.
Node.js propose certaines options et outils pour configurer et dboguer des problmes mmoires. Ces fonctionnalits peuvent ne pas tre disponibles dans les environnements navigateur.
La quantit de mmoire pour la mmoire du tas (heap) peut tre augmente avec une option :
node --max-old-space-size=6000 index.js
On peut galement exposer le ramasse-miettes afin de dboguer des problmes mmoires. Cela s'active via une option et s'utilise avec le dbogueur Chrome :
node --expose-gc --inspect index.js
Cette page a t modifie le 7 sept. 2025 par les contributeurices du MDN.
Certaines parties de ce contenu sont protges par le droit d'auteur 19982026 des contributeurs individuels de mozilla.org. Contenu disponible sous une licence Creative Commons.
| Web Proxy Viewer | New URL | Original Page |