Forzar la recolección de basura para que se ejecute en R con el comando gc ()

Periódicamente programo descuidadamente. Ok, programo descuidadamente todo el tiempo, pero a veces eso me alcanza en forma de errores de falta de memoria. Empiezo a ejercitar un poco de disciplina al eliminar objetos con el comando rm () y las cosas mejoran. Veo mensajes mixtos en línea sobre si debo llamar explícitamente a gc () después de eliminar objetos de datos grandes. Algunos dicen que antes de que R devuelva un error de memoria ejecutará gc () mientras que otros dicen que forzar manualmente gc es una buena idea.

¿Debo ejecutar gc () después de eliminar objetos grandes para garantizar la máxima disponibilidad de memoria?

“Probablemente.” Lo hago también, y a menudo incluso en un bucle como en

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

Sin embargo, eso no significa, en mi experiencia, restaurar la memoria a un estado prístino.

Entonces, lo que suelo hacer es mantener las tareas a mano en los archivos de script y ejecutarlos usando la interfaz 'r' (en Unix, y desde el paquete 'littler'). Rscript es una alternativa en ese otro sistema operativo.

Ese flujo de trabajo pasa a estar de acuerdo con

  • workflow-for-statistics-analysis-and-informe-escritura
  • tricks-to-manage-the-available-memory-in-an-r-session

que cubrimos aquí antes.

Desde la página de ayuda en gc :

Una llamada de ‘gc’ hace que se realice una recolección de basura. Esto también se llevará a cabo automáticamente sin la intervención del usuario, y el propósito principal de llamar a ‘gc’ es para el informe sobre el uso de la memoria.

Sin embargo, puede ser útil llamar a ‘gc’ después de que se haya eliminado un objeto grande, ya que esto puede hacer que R devuelva la memoria al sistema operativo.

Por lo tanto, puede ser útil hacerlo, pero sobre todo no debería tener que hacerlo. Mi opinión personal es que es un código de último recurso: no debe ensuciar su código con las declaraciones de gc() como una cuestión de rutina, pero si su máquina sigue cayendo, y usted ha intentado todo lo demás, entonces podría ser útil.

Por todo lo demás, me refiero a cosas como

  1. Funciones de escritura en lugar de scripts sin procesar, por lo que las variables quedan fuera del scope.

  2. Vaciar su espacio de trabajo si pasa de un problema a otro no relacionado.

  3. Descartar datos / variables que no le interesan (frecuentemente recibo hojas de cálculo con docenas de columnas que no interesan).

Un poco tarde para la fiesta, pero:

Llamar explícitamente a gc liberará algo de memoria “ahora”. … entonces, si otros procesos necesitan la memoria, podría ser una buena idea. Por ejemplo, antes de llamar al system o similar. O tal vez cuando esté “listo” con el guión y R permanecerá inactivo por un tiempo hasta que llegue el próximo trabajo, de nuevo, para que otros procesos obtengan más memoria.

Si solo quieres que tu script se ejecute más rápido, no importará ya que R lo llamará más tarde si es necesario. Incluso podría ser más lento ya que el ciclo GC normal podría no haber necesitado llamarlo.

… pero si quiere medir el tiempo, por ejemplo, generalmente es una buena idea hacer un GC antes de ejecutar su prueba. Esto es lo que system.time hace por defecto.

ACTUALIZACIÓN Como @DWin señala, R (o C #, o Java, etc.) no siempre sabe cuando la memoria es baja y el GC necesita ejecutarse. Por lo tanto, a veces podría necesitar hacer GC como solución para las deficiencias en el sistema de memoria.

Supuestamente, R solo usa RAM. Eso no es cierto en una Mac (y sospecho que tampoco es cierto en Windows.) Si se queda sin memoria RAM, comenzará a usar la memoria virtual. A veces, pero no siempre, los procesos ‘reconocerán’ que necesitan ejecutar gc () y liberar memoria. Cuando no lo hacen, puedes ver esto usando ActivityMonitor.app y viendo que toda la memoria RAM está ocupada y el acceso al disco ha aumentado. Cuando hago grandes regresiones de Cox, descubro que puedo evitar el derrame en la memoria virtual (con acceso lento al disco) al realizar llamadas anteriores con gc(); cph(...) gc(); cph(...)

No. Si no hay suficiente memoria disponible para una operación, R ejecutará gc() automáticamente.

“Tal vez.” Realmente no tengo una respuesta definitiva. Pero el archivo de ayuda sugiere que en realidad solo hay dos razones para llamar a gc ():

  1. Desea un informe de uso de memoria.
  2. Después de eliminar un objeto grande, “puede solicitar a R que devuelva la memoria al sistema operativo”.

Como puede ralentizar una simulación grande con llamadas repetidas, tendí a hacerlo solo después de eliminar algo grande. En otras palabras, no creo que tenga sentido llamarlo sistemáticamente todo el tiempo a menos que tenga una buena razón para hacerlo.