memoria limpiar aumentar r garbage-collection

limpiar - ¿Por qué gc() no libera memoria?



aumentar memoria en r (2)

Ejecuto simulaciones en una computadora Windows de 64 bits con 64 GB de RAM . El uso de la memoria alcanza el 55% y después de una ejecución de simulación terminada, elimino todos los objetos en el espacio de trabajo mediante rm(list=ls()) , seguido de una double gc() .

Supuse que esto liberaría suficiente memoria para la siguiente ejecución de simulación, pero en realidad el uso de memoria se reduce en solo un 1% . Consultando muchos foros diferentes, no pude encontrar una explicación satisfactoria, solo comentarios vagos como:

"Dependiendo de su sistema operativo, la memoria liberada podría no devolverse al sistema operativo, sino mantenerse en el espacio de proceso".

Me gustaría encontrar información sobre:

  • 1) qué sistema operativo y en qué condiciones no se devuelve la memoria liberada al sistema operativo, y
  • 2) ¿Hay algún otro remedio que no sea cerrar R y comenzar de nuevo para la siguiente ejecución de simulación?

¿Cómo se verifica el uso de la memoria? Normalmente, la máquina virtual asigna parte de la memoria que utiliza para almacenar sus datos. Algunos de los asignados pueden estar sin uso y marcarse como libres. Lo que GC hace es descubrir datos a los que no se hace referencia en ningún otro lugar y marcar los fragmentos de memoria correspondientes como no utilizados, esto no significa que esta memoria se libere al sistema operativo. Aún desde la perspectiva de la VM, ahora hay más memoria libre que se puede usar para cálculos adicionales.

Como otros preguntaron, ¿experimentaste errores de memoria? Si no, entonces no hay nada de qué preocuparse.

EDIT: This y this debería ser suficiente para comprender cómo funciona la asignación de memoria y la recolección de basura en R.

Desde el primer documento:

Ocasionalmente, se intenta devolver las páginas no utilizadas al sistema operativo. Cuando se publican las páginas, se retiene un número de nodos libres igual a R_MaxKeepFrac por el número de nodos asignados para cada clase. Se publican las páginas que no son necesarias para cumplir con este requisito. Se realiza un intento de liberar páginas en todas las colecciones de nivel 1 o nivel 2 de R_PageReleaseFreq.

EDIT2:

Para ver la memoria usada, intente ejecutar gc () con el ajuste detallado en VERDADERO:

gc(verbose=T)

Aquí hay un resultado con una matriz de 10''000''000 enteros en la memoria:

Garbage collection 9 = 1+0+8 (level 2) ... 10.7 Mbytes of cons cells used (49%) 40.6 Mbytes of vectors used (72%) used (Mb) gc trigger (Mb) max used (Mb) Ncells 198838 10.7 407500 21.8 350000 18.7 Vcells 5311050 40.6 7421749 56.7 5311504 40.6

Y aquí está después de descartar la referencia a ella:

Garbage collection 10 = 1+0+9 (level 2) ... 10.7 Mbytes of cons cells used (49%) 2.4 Mbytes of vectors used (5%) used (Mb) gc trigger (Mb) max used (Mb) Ncells 198821 10.7 407500 21.8 350000 18.7 Vcells 310987 2.4 5937399 45.3 5311504 40.6

Como se puede ver, la memoria utilizada por Vcells cayó de 40.6Mb a 2.4Mb.


El recolector de basura R es imperfecto de la siguiente manera (no tan) sutil: no mueve objetos (es decir, no compacta la memoria) debido a la forma en que interactúa con las bibliotecas de C (Algunos other lenguajes / implementaciones también sufren esto, pero otros , a pesar de tener que interactuar con C , logran tener un GC generacional compacto que no sufre este problema).

Esto significa que si se turnan para asignar pequeños trozos de memoria que luego se descartan y trozos más grandes para objetos más permanentes (esta es una situación común al procesar cadenas / expresiones regulares), entonces su memoria se fragmented y el recolector de basura no puede hacer nada al respecto it: la memoria se libera, pero no se puede reutilizar porque los fragmentos libres son demasiado cortos.

La única forma de solucionar el problema es guardar los objetos que desea, reiniciar R y volver a cargar los objetos.

Ya que está haciendo rm(list=ls()) , es decir, no necesita ningún objeto, no necesita guardar y volver a cargar nada, por lo que, en su caso, la solución es precisamente lo que desea evitar: reiniciar R .

PD. La recolección de basura es un tema altamente no trivial. Por ejemplo, Ruby utilizó 5 (!) Algoritmos GC diferentes durante 20 años . Java GC no apesta porque Sun / Oracle e IBM gastaron muchos años de programador en sus respectivas implementaciones del GC. Por otro lado, R y Python tienen pésimo GC, porque nadie se molestó en invertir los años-hombre necesarios, y son muy populares. Eso es worse-is-better para ti.