2015-03-30 9 views
9

considerare questo pezzo di torta ... ehm, il codice:Questa funzione può essere raccolta automaticamente?

'use strict' 

function doWork() { 
    return new Promise(function (resolve, reject) { 
    // work work work... 
    // Done! But... where's the resolve() ??? 
    }) 
} 

doWork().then(function doMoreWork() { 
    // Some more work to do... 
}) 

volta che la funzione nel costruttore di Promise finisce ...

  1. È l'oggetto Promise garbage-da collezione?
  2. È doMoreWork() immondizia da collezione?

mia ipotesi è che doMoreWork() non può essere GC-ed direttamente perché la promessa mantiene un riferimento ad esso, ma una volta che le finiture del corpo del promessa e restituisce il contesto di esecuzione per la portata superiore (?), I snoda pila (perché non ci sono più dichiarazioni da eseguire) e la Promessa diventa irraggiungibile, quindi essere spazzatura-raccoglibile.

Potete confermare che la mia comprensione di questo argomento è corretta?

Come posso osservare empiricamente questo comportamento? In altre parole, come posso monitorare quali oggetti sono in GC-ed e quando? Mi sviluppo puramente in Node.js, se questo fa alcuna differenza.

+0

Vuoi dire che il tuo lavoro non chiama mai 'resolve()'? Sì, in quel caso tutti i tuoi oggetti sarebbero sospetti di gc immediatamente. – Bergi

risposta

1

Non c'è nulla che mantenga il riferimento alla promessa, quindi sarà raccolta della spazzatura. La promessa è l'unica cosa che mantiene il riferimento alla funzione doMoreWork quindi sarà anche garbage collection.

Come è possibile osservare empiricamente questo comportamento? In altre parole, come posso monitorare quali oggetti sono GC-ed e quando? Mi sviluppo puramente in Node.js, se questo fa alcuna differenza.

Il GC in V8 non raccoglie mai necessariamente un oggetto. Ad esempio, se questo è il tuo intero programma, sarebbe una perdita di tempo prima di eseguire qualsiasi GC.

0
  1. L'oggetto Promise è raccoglibile se non ha riferimenti che puntano ad esso. Se viene utilizzato doWork().then(...), viene creato un riferimento temporaneo. Così fino a quando .then non blocca più v'è un riferimento all'oggetto in modo che non possono essere raccolti
  2. Hai ragione, doMoreWork non è anche da collezione, perché l'oggetto Promise ha un riferimento ad esso

La dichiarazione doWork().then(...) può essere sostituito da

new Promise(function (resolve, reject) { 
    // work work work... 
}).then(function doMoreWork() { 
      // Some more work to do... 
     }) 

quindi potete immaginare che si sta utilizzando direttamente l'oggetto Promise, in modo che il "superiore" -Scope è dove viene utilizzato l'oggetto.

Gli oggetti vengono generalmente raccolti quando non ci sono più riferimenti ad esso. Anche se il codice è in una Promessa è solo un oggetto e la chiamata a then è concatenata, quindi l'oggetto viene utilizzato

+0

Penso che la risposta di Esailija dovrebbe essere giusta, ma non può essere dimostrata senza conoscere l'implementazione di Promise. La Promessa viene creata, una sola chiamata .then() viene eseguita su di essa, quindi, in base al codice, non viene utilizzata, quindi la promessa e quindi l'argomento di then() possono essere entrambi riciclati. Ma, cosa succede se la tua implementazione Promessa mantiene una sorta di elenco interno o una tabella di promesse che vengono create? Forse li libera quando è risolto; forse mai. La mia ipotesi è che non scrivano le implementazioni di Promessa in questo modo; ma non ci sono prove. Ad ogni modo, il tuo programma JS non può dire la differenza. – OsamaBinLogin

0

Per verificare se un oggetto è obsoleto, è possibile creare un test e individuare la perdita di memoria (tramite il task manager). Se il tuo codice è scritto correttamente, tutto viene raccolto.

Problemi correlati