web-dev-qa-db-fra.com

Comment effacez-vous la mémoire en Javascript?

var Obj = function(){}; var X = new Obj();

X = null effacera-t-il correctement la mémoire?

Est-ce que cela serait équivalent?

var Obj = function(){}; 
var X   = {}; 
X.obj   = new Obj();
delete(X.obj);

EDITIl semblerait que supprimer X.obj n'efface PAS immédiatement la mémoire, cela aiderait la récupération de place. Si je ne supprime pas X.obj, il y aura toujours un pointeur sur un objet et le GC ne pourra donc pas le nettoyer.

Bien que je choisis la réponse de @ delnan, si vous lisez ceci, vous devriez également lire l'article de Benubird.

J'ai aussi remarqué que j'avais accidentellement écrit delete (X) à la place de delete (X.obj) - désolé.

19
Dave Stein

La réponse courte est que vous ne le faites pas. delete supprime simplement une référence (et non de la façon dont vous essayez de l'utiliser, voir le lien ci-dessus - delete est l'une de ces fonctionnalités linguistiques que peu de gens comprennent réellement), rien de plus. L’implémentation efface la mémoire pour vous, mais ce n’est pas votre affaire (et même si, à proprement parler - c’est pourquoi on ne devrait pas s’appuyer sur des finaliseurs dans les langues de GC'd qui les proposent), c’est le cas. Notez cependant:

  • Seuls les objets dont il est prouvé qu’ils sont inaccessibles (c’est-à-dire qu’aucun moyen d’y accéder) de tout le code peuvent être supprimés. Ce qui garde des références à qui est généralement assez évident, du moins conceptuellement. Vous devez simplement faire attention aux nombreuses fermetures, car elles peuvent capturer plus de variables que vous ne le pensez. Notez également que les références circulaires sont nettoyées correctement.
  • Il y a un bogue dans les anciennes versions (mais malheureusement toujours utilisées) IE impliquant la récupération de place des gestionnaires d'événements JS et des éléments DOM. Google (peut-être même SO) devrait avoir un meilleur matériel sur ma mémoire.

Sur le plan positif, cela signifie que vous ne rencontrerez pas de bogues de pointeur ni de fuites de mémoire (sauf les pièges susmentionnés).

18
user395760
15
Benubird

Non - Javascript exécute GC quand il le faut.

4
Ed Heal

La méthode Delete supprime uniquement la référence, pas l'objet. Toute autre référence serait laissée en attente du collecteur de mémoire.

JavaScript a son propre GC, et il va courir et nettoyer les choses quand plus rien ne se réfère à eux.

Je pense toujours que c’est une bonne pratique d’annuler des objets. Supprimer un objet aide également le GC, car il va voir quelque chose en suspens, et dit «Je vais vous manger parce que vous êtes tout seul (et rire cynique) ".

Vous devriez regarder Supprimer des objets en JavaScript

Même s'il existe un GC, vous voulez toujours vous assurer que votre script est optimisé pour la performance, car les ordinateurs, les navigateurs et les barres d'outils Fricken (et leur nombre) varient. 

3
Ryan Ternier

De manière générale, la gestion de la mémoire en Javascript est spécifique à un agent utilisateur. Le principe de base du ramasse-miettes est le comptage de références. Ainsi, en définissant une référence sur null (à l'aide du mot clé delete ou par une affectation explicite), vous pouvez vous assurer qu'une référence sera nettoyée,SIl'objet ne contient aucune référence qui vivra. en dehors de sa portée de création. Dans ce cas, le GC aura déjà nettoyé tous les objets ou variables dont la portée s'est terminée sans que vous le définissiez explicitement à null.

Cependant, il y a certaines choses à prendre en compte: les références circulaires sont faciles à créer dans JS, notamment entre un élément DOM et un objet. Il faut prendre soin de supprimer (ou de ne pas créer en premier lieu) les références aux éléments DOM et/ou à partir de ceux-ci au sein des objets. Si vous créez une référence to/from liée à DOM, veillez à les nettoyer explicitement en définissant les références sur null, à la fois sur votre objet et sur l'élément DOM. Définir simplement un objet parent sur null ne suffit pas s'il existe des objets enfants avec des références à/depuis DOM ou localStorage, car ces références demeureront, et s'il y avait une référence de l'enfant au parent, le parent demeurera ensuite mémoire à cause de cette référence.

Les pages Web peuvent en réalité laisser des traces dans votre mémoire. Lorsque vous vous écartez, les références circulaires conservent les objets et les éléments DOM en mémoire jusqu'à ce que vous ayez redémarré le navigateur!

Un article sur le sujet: http://docstore.mik.ua/orelly/webprog/jscript/ch11_03.htm et un autre aspect détaillé: http://blogs.msdn.com/b/ericlippert /archive/2003/09/17/53038.aspx

1
Chris Baker

La mémoire JavaScript est généralement gérée de la même manière qu'en Java - je veux dire qu'il existe (ou devrait avoir) un ramasse-miettes qui effacerait l'objet s'il n'y avait pas de référence. Donc, oui, simplement "annuler" la référence est la seule façon de "manipuler" la libération de mémoire, et la libération réelle est la partie hôte JS.

0
yosh kemu