2015-06-05 14 views
6

Sto utilizzando il nodo e sto considerando l'esecuzione manuale della garbage collection nel nodo. C'è qualche svantaggio su questo? La ragione per cui sto facendo questo è che sembra che il nodo non stia eseguendo la raccolta dei dati inutili abbastanza frequentemente. Qualcuno sa quanto spesso V8 fa la sua routine di garbage collection nel nodo?Esecuzione della garbage collection manualmente nel nodo

Grazie!

+2

quale problema si è veramente cercando di risolvere (mostrarci codice rilevante) e come stai misurando l'utilizzo della memoria. Ho il sospetto che tu abbia un problema di misurazione piuttosto che un problema di garbage collection poiché la garbage collection viene eseguita nel tempo di inattività node.js e di solito è un problema solo se hai un vero e proprio thread di esecuzione che crea molti oggetti temporanei. In un normale ambiente server node.js, ci dovrebbe essere un sacco di tempo di inattività (quando si utilizza la corretta programmazione asincrona). – jfriend00

+0

Può valere la pena leggere questo articolo: https://strongloop.com/strongblog/node-js-performance-garbage-collection/ – jfriend00

+0

Sto usando ps --sort -rss -eo rss, pid, comando | testa per il controllo della memoria. Sto usando un server Amazon (livello gratuito) in modo che ci sia solo 1 gig di memoria. Se inizio a eseguire più istanze della mia app su questo e non lo raccolgo manualmente, l'utilizzo della memoria salta alle stelle fino a quando il server non si blocca. –

risposta

0

V8 Eseguire la raccolta dei rifiuti quando pensa che sia interessante. Non c'è un ritardo fisso per quello. È possibile leggere questo articolo per informazioni sulla garbage collection V8: https://strongloop.com/strongblog/node-js-performance-garbage-collection/

In ogni caso è una cattiva idea eseguire manualmente il garbage collector nel progetto perché ha bloccato completamente il processo del nodo. Quindi durante la garbage collection il tuo programma non gestirà alcuna richiesta.

11

In realtà ho avuto lo stesso problema con nodo in esecuzione su heroku con istanze da 1 GB.

Durante l'esecuzione del server nodo sul traffico di produzione, la memoria aumentava costantemente fino a quando non superava il limite di memoria, causandone l'esecuzione lentamente.

Questo è probabilmente causato dall'app che genera molta spazzatura, serve principalmente le risposte API JSON. Ma non era una perdita di memoria, solo spazzatura non raccolta.

Sembra che il nodo non abbia la priorità di fare abbastanza raccolte di dati inutili sul vecchio spazio oggetti per la mia app, quindi la memoria crescerà costantemente.

Eseguire global.gc() manualmente (abilitato con nodo --expose_gc) ridurrebbe l'utilizzo della memoria di 50 MB ogni volta e metterebbe in pausa l'app per circa 400ms.

Quello che ho finito è eseguire gc manualmente su una pianificazione randomizzata (in modo che le istanze di heroku non facessero GC tutto in una volta). Ciò ha ridotto l'utilizzo della memoria e ha fermato la quota di memoria ha superato gli errori.

Una versione semplificata potrebbe essere qualcosa di simile:

function scheduleGc() { 
    if (!global.gc) { 
    console.log('Garbage collection is not exposed'); 
    return; 
    } 

    // schedule next gc within a random interval (e.g. 15-45 minutes) 
    // tweak this based on your app's memory usage 
    var nextMinutes = Math.random() * 30 + 15; 

    setTimeout(function(){ 
    global.gc(); 
    console.log('Manual gc', process.memoryUsage()); 
    scheduleGc(); 
    }, nextMinutes * 60 * 1000); 
} 

// call this in the startup script of your app (once per process) 
scheduleGc(); 

È necessario eseguire la vostra applicazione con la raccolta dei rifiuti a vista:

node --expose_gc app.js 
+0

Spero davvero che funzioni perché questo mi ha infastidito per una settimana. Ho persino aggiornato lo standard 2x solo per scoprire che l'app finirà per consumare la quantità di memoria che gli hai dato. – lwdthe1

+0

Nessuna fortuna, penso che in realtà abbia peggiorato il problema perché la mia app ha ancora mangiato memoria e la garbage collection manuale ha fermato la reattività della mia app . – lwdthe1

2

So che questo può essere un po 'di una risposta tardiva a aiuto per OP, ma ho pensato che avrei collaborato alle mie recenti esperienze con l'allocazione della memoria e la garbage collection del Nodo JS.

Attualmente stiamo lavorando su un server JS nodo in esecuzione su un raspberry pi 3. Ogni tanto si blocca a causa di esaurimento della memoria. Inizialmente pensavo che si trattasse di una perdita di memoria, e dopo una settimana e mezza di ricerca nel mio codice e nessuna idea, ho pensato che il problema avrebbe potuto essere esacerbato dal fatto che Node JS assegna più memoria di quella disponibile su Rpi3 per i suoi processi prima che faccia il GC.

Sono stato in esecuzione di nuove istanze di un server con i seguenti comandi:

'nodo server.js --max-eseguibile-size = 96 --max-old-spazio-size = 128 --max -semi-space-size = 2 '

Ciò limita in modo efficace la quantità totale di spazio che il nodo può occupare sul computer locale e impone che le raccolte di dati inutili vengano eseguite più frequentemente.Finora, stiamo assistendo a un uso costante della memoria e mi conferma che il mio codice non stava perdendo inizialmente, ma piuttosto il nodo stava allocando più memoria del possibile.

MODIFICA: questo collegamento delinea in termini più specifici il problema con cui ho avuto a che fare.

-nodejs decrease v8 garbage collector memory usage - https://github.com/nodejs/node/issues/2738