2013-05-09 10 views
5

Quando abbiamo iniziato a testare il nostro progetto NodeJS abbiamo notato un enorme consumo di memoria. È causato da perdite di memoria in tutto il nostro progetto. Quindi abbiamo iniziato a cercare tutte le cause che possono causare perdite di memoria. Ci sono alcune risposte a questa domanda su StackOverflow, ma non esiste alcun documento più preciso su cosa sia e cosa non sia una perdita di memoria.Perdite di memoria e problemi di chiusura in NodeJS

Le mie domande:

  • Esiste un documento sul V8 GC e come funziona (in dettaglio)?
  • Come rilasciare le richiamate in modo che GC possa raccoglierle?
  • Il V8 GC raccoglie le variabili che non vengono utilizzate ma c'è una chiusura di funzione sotto di esse? Esempio:

    var serviceChannel = require('./channel'); 
    var dataRegistration = require('../data/registration'); 
    
    function registerOnChannel(userID, channelID, callsuccess, callerror) { 
    
        serviceChannel.findChannel(channelID, function (channel) { 
         if (!channel) { 
          callerror("Channel doesn' exists"); 
          return; 
         } 
         dataRegistration.registerOnChannel(userID, channelID, function (registration) { 
          if (!registration) { 
           callerror("Registration doesn' exists"); 
           return; 
          } 
          callsuccess("Registration successful"); 
         }, function (error) { 
          callerror("Error on registration"); 
         }) 
        }, function (error) { 
         callerror("Error on finding channel"); 
        }) 
    } 
    

Così, serviceChannel e dataRegistration verrà mantenuto in memoria fino a quando registerOnChanel è dal vivo. Ma il canale variabile sarà cancellato dal GC (non è utilizzato da alcuna funzione)?

+0

"Così, serviceChannel e dataRegistration verranno mantenuti in memoria finché registerOnChanel è attivo". Come vieni a questa conclusione? –

+0

È una chiusura. –

+0

Non ci sono prove di chiusura nel codice che hai postato, almeno non in modo tale da mantenere in vita ServiceChannel o DataRegistration. –

risposta

0

Per prima cosa, direi che dovresti spostare la tua API per utilizzare lo strumento integrato EventEmitter (http://nodejs.org/api/events.html).

Il V8 GC raccoglie variabili che non vengono utilizzate, ma c'è una chiusura di funzione sotto di esse?

Se si utilizza una variabile da una precedente funzione di portata poi la variabile dovrà restare fino a quando la portata funzione di contenimento, e tutte le richiamate che contengono quella variabile, sono andati fuori del campo di applicazione.

Ma il canale variabile verrà eliminato dal GC (non viene utilizzato da alcuna funzione)?

In base all'esempio di codice che hai pubblicato, sì, verrà raccolto da GC. Ma è molto possibile aver fatto trapelare un riferimento o due senza accorgersene.

+0

Ho testato NodeJS con alcune varianti di questo esempio e GC rimuove sempre oggetti e variabili quando nessuno fa riferimento a essi. Ho anche notato che GC funziona solo se ce n'è bisogno (modalità lazy). Se il programma consuma un po 'di memoria, non verrà rilasciato fino a quando non viene fatta una nuova richiesta di allocazione di memoria. V8 GC funziona molto bene. –

Problemi correlati