Forzare la garbage collection per l’esecuzione in R con il comando gc ()

Periodicamente programma in modo sleale. Ok, programma tutto in modo sconnesso tutto il tempo, ma a volte questo mi raggiunge sotto forma di errori di memoria insufficienti. Comincio ad esercitare un po ‘di disciplina nell’eliminazione degli oggetti con il comando rm () e le cose migliorano. Vedo messaggi misti online su se dovrei chiamare esplicitamente gc () dopo aver cancellato oggetti di grandi dimensioni. Alcuni dicono che prima che R restituisca un errore di memoria, eseguirà gc () mentre altri dicono che forzare manualmente gc è una buona idea.

Devo eseguire gc () dopo aver cancellato oggetti di grandi dimensioni per garantire la massima disponibilità di memoria?

“Probabilmente.” Lo faccio anche io, e spesso anche in loop come in

cleanMem <- function(n=10) { for (i in 1:n) gc() } 

Eppure, in base alla mia esperienza, ciò non ripristina la memoria in uno stato originario.

Quindi quello che faccio di solito è mantenere i compiti a portata di mano nei file di script ed eseguire quelli che usano il frontend 'r' (su Unix e dal pacchetto 'littler'). Rscript è un'alternativa su quell'altro OS.

Questo stream di lavoro è d'accordo con

  • workflow-for-statistico-analisi-e-rapporto-scrittura
  • trucchi da gestire-the-disponibile-memory-in-an-r-session

di cui abbiamo parlato qui prima.

Dalla pagina di aiuto su gc :

Una chiamata di ‘gc’ fa sì che una garbage collection abbia luogo. Ciò avverrà automaticamente anche senza l’intervento dell’utente e lo scopo principale della chiamata ‘gc’ è per il report sull’utilizzo della memoria.

Tuttavia, può essere utile chiamare ‘gc’ dopo che un object di grandi dimensioni è stato rimosso, in quanto ciò potrebbe richiedere a R di restituire memoria al sistema operativo.

Quindi può essere utile da fare, ma soprattutto non dovresti. La mia opinione personale è che si tratta di un codice di ultima istanza: non si dovrebbe mai sporcare il proprio codice con le istruzioni gc() , ma se la vostra macchina continua a cadere e avete provato tutto il resto, allora potrebbe Sii utile.

Per tutto il resto, intendo cose come

  1. Scrivere le funzioni piuttosto che gli script non elaborati, quindi le variabili escono dall’ambito di applicazione.

  2. Svuotare lo spazio di lavoro se passi da un problema a un altro non correlato.

  3. Eliminazione di dati / variabili a cui non sei interessato. (Ricevo spesso fogli di calcolo con dozzine di colonne non interessanti).

Un po ‘tardi alla festa, ma:

Chiamare esplicitamente gc memoria “adesso”. … quindi se altri processi hanno bisogno di memoria, potrebbe essere una buona idea. Ad esempio prima di chiamare il system o simili. O forse quando hai “finito” con la sceneggiatura e R resterà inattivo per un po ‘fino all’arrivo del prossimo lavoro, ancora una volta, in modo che altri processi ottengano più memoria.

Se vuoi solo che il tuo script funzioni più velocemente, non importa, dato che R lo chiamerà più tardi se necessario. Potrebbe anche essere più lento poiché il ciclo normale del GC potrebbe non aver mai avuto bisogno di chiamarlo.

… ma se si desidera misurare il tempo, ad esempio, è generalmente una buona idea fare un GC prima di eseguire il test. Questo è ciò che system.time fa di default.

AGGIORNAMENTO Come @DWin indica, R (o C #, o Java ecc.) Non sempre sanno quando la memoria è bassa e il GC deve essere eseguito. Quindi a volte potresti avere bisogno di fare GC come soluzione per carenze nel sistema di memoria.

Presumibilmente R utilizza solo RAM. Questo non è vero su un Mac (e ho il sospetto che non sia vero nemmeno su Windows). Se esaurisce la RAM, inizierà a utilizzare la memoria virtuale. A volte, ma non sempre, i processi riconosceranno che devono eseguire gc () e liberare memoria. Quando non lo fanno, puoi vederlo usando ActivityMonitor.app e vedendo che tutta la RAM è occupata e l’accesso al disco è saltato in alto. Trovo che quando sto facendo grandi esecuzioni di regressione di Cox, posso evitare di riversare nella memoria virtuale (con accesso lento al disco) facendo precedere le chiamate con gc(); cph(...) gc(); cph(...)

No. Se non c’è abbastanza memoria disponibile per un’operazione, R eseguirà automaticamente gc() .

“Può essere.” Non ho una risposta definitiva. Ma il file di aiuto suggerisce che ci sono davvero solo due ragioni per chiamare gc ():

  1. Vuoi un rapporto sull’uso della memoria.
  2. Dopo aver rimosso un object di grandi dimensioni, “potrebbe richiedere a R di restituire memoria al sistema operativo.”

Dal momento che può rallentare una grande simulazione con chiamate ripetute, ho avuto la tendenza a farlo solo dopo aver rimosso qualcosa di grande. In altre parole, non penso che abbia senso chiamarlo sistematicamente tutto il tempo a meno che non si abbia una buona ragione per farlo.