2011-08-30 19 views
17

var Obj = function(){}; var X = new Obj();Come si cancella la memoria in Javascript?

X = null memoria correttamente corretta?

Anche questo sarebbe equivalente?

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

EDIT Sembrerebbe che, anche se l'eliminazione di X.obj sarebbe non immediatamente cancellare la memoria, sarebbe utile la raccolta dei rifiuti. Se non elimini X.obj, ci sarebbe comunque un puntatore a un oggetto e quindi il GC potrebbe non pulirlo.

Anche se sto raccogliendo la risposta di @ delnan, se stai leggendo questo dovresti anche prendere l'articolo di Benubird.

Mi accorgo anche che ho originariamente scritto delete (X) in origine invece di delete (X.obj) - sorry.

+0

Si dovrebbe spiegare perché sei interessato a "memoria cancellata". Riduce l'utilizzo della RAM? O per sicurezza? O qualche altra ragione? –

+0

Per ridurre l'utilizzo della RAM/assicurarsi che il GC lo tocchi –

+0

Mi piace questa domanda. Sfortunatamente come con la maggior parte degli ambienti gestiti dalla memoria, l'approccio migliore è lasciare che il GC faccia il suo lavoro. Oh, e stai attento ai riferimenti. –

risposta

15

La risposta breve è che non lo fanno. delete rimuove semplicemente un riferimento (e non nel modo in cui si tenta di usarlo, si veda il link sopra - delete è una di quelle funzionalità linguistiche che in realtà solo poche persone capiscono), niente di più. L'implementazione cancella la memoria per te, ma non è il tuo business quando (e anche se, a rigor di termini - questo è il motivo per cui non si deve fare affidamento sui finalizzatori nelle lingue di GC che li offrono) lo fa. Nota:

  • Solo gli oggetti che possono essere dimostrati irraggiungibili (cioè non è possibile accedervi) a tutto il codice possono essere rimossi. Ciò che mantiene i riferimenti a chi di solito è abbastanza ovvio, almeno dal punto di vista concettuale. Devi solo stare attento quando parli di molte chiusure, poiché potrebbero catturare più variabili di quanto pensi. Si noti inoltre che i riferimenti circolari sono puliti correttamente.
  • C'è un errore nelle vecchie versioni (ma purtroppo ancora utilizzate) di IE che coinvolgono la garbage collection di gestori di eventi JS e elementi DOM. Google (forse anche SO) dovrebbe avere materiale migliore nella mia memoria.

Per quanto riguarda i lati positivi, ciò significa che non si verificheranno problemi con puntatori del puntatore o perdite di memoria (ad eccezione ovviamente delle suddette).

+0

Quindi nell'esempio di codice precedente, wouldn ' t il nuovo Obj() viene rimosso dalla memoria tramite garbage collection, poiché nulla lo indica più? –

+0

Dopo il primo snippet, l'oggetto creato non viene più referenziato e può quindi essere raccolto. Il secondo usa in modo errato 'delete' (vedi il link di Benubird) e il risultato dipende dal fatto che l'implementazione ti permetta di eliminare le variabili, ma se lo fa, non c'è alcun riferimento residuo. Altrimenti, gli oggetti possono diventare garbage collection non appena 'X' cade dall'ambito. In ogni caso, la memoria viene liberata * ad un certo punto nel tempo * dopo (NON immediatamente, a meno che non si tratti di una possibilità incredibile) dopo che l'oggetto non è più raggiungibile. – delnan

+0

Ho appena notato che ho fatto un refuso nel mio frammento. Voglio dire eliminare (X.obj). Quindi dovrei eliminare (X.obj) o X.obj = null per accelerare GC? –

3

No - Javascript esegue GC quando lo si desidera.

13
+0

Grazie per questo. – ZenMaster

+1

+1 ottimo articolo –

+0

Sebbene questo collegamento possa rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. – Mistalis

2

Il metodo Elimina elimina solo il riferimento, non l'oggetto. Eventuali altri riferimenti sarebbero lasciati fuori in attesa del garbage collector.

JavaScript ha il proprio GC e gira intorno e ripulisce le cose quando non vi si riferisce più a loro.

Continuo a pensare che sia una buona pratica per oggetti nulli. Eliminare un oggetto aiuta anche il GC perché vedrà qualcosa penzolare e dire "Ti mangerò perché sei tutto solo (e ora ridi cinicamente)".

Si dovrebbe guardare Deleting Objects in JavaScript

Anche se c'è un GC, si vuole ancora per assicurare lo script è ottimizzato per le prestazioni come popoli computer, browser e le barre degli strumenti fricken (e il numero di essi), varierà.

0

La memoria JavaScript viene generalmente gestita in modo simile a Java. Voglio dire che c'è (o ci dovrebbe essere) un garbage collector che eliminerebbe l'oggetto se non ci sono riferimenti ad esso. Quindi sì, semplicemente "annullando" il riferimento è l'unico modo per "gestire" la liberazione della memoria e la vera liberazione è la parte host JS.

1

In generale, la gestione della memoria in Javascript è specifica per utente-agente. Le basi del garbage collector sono attraverso il conteggio dei riferimenti. Quindi, impostando un riferimento a null (usando la parola chiave delete o esplicitamente), puoi assicurarti che un riferimento verrà ripulito, SE l'oggetto non ha riferimenti che vivranno al di fuori del suo ambito di creazione. Stando così le cose, il GC avrà già ripulito tutti gli oggetti o le variabili il cui ambito è terminato senza averlo impostato esplicitamente su null.

Ci sono alcune cose di cui occuparsi, tuttavia - i riferimenti circolari sono facili da creare in JS, specialmente tra un elemento DOM e un oggetto. Bisogna fare attenzione a cancellare (o non creare in primo luogo) riferimenti a e/o elementi DOM all'interno degli oggetti. Se crei un to/from reference relativo al DOM, assicurati di pulirlo esplicitamente impostando i riferimenti a null - sia sul tuo oggetto che sull'elemento DOM. Semplicemente impostando un oggetto genitore su null non è sufficiente se ci sono oggetti figlio con riferimenti a/da DOM o localStorage perché quei riferimenti vivranno, e se ci fosse qualche riferimento dal figlio al genitore, allora il genitore sopravviverà in memoria a causa di quel riferimento.

Le pagine Web possono in realtà infiltrarsi nella memoria in questo modo: una volta allontanati, i riferimenti circolari conservano gli oggetti e gli elementi DOM in memoria finché non si riavvia il browser!

Un articolo sul tema: http://docstore.mik.ua/orelly/webprog/jscript/ch11_03.htm, e un altro sguardo dettagliato: http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx

Problemi correlati