R gestión de memoria / no puede asignar vector de tamaño n Mb

149

Me encuentro con problemas al tratar de usar objetos grandes en R. Por ejemplo:

> memory.limit(4000)
> a = matrix(NA, 1500000, 60)
> a = matrix(NA, 2500000, 60)
> a = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb
> a = matrix(NA, 2500000, 60)
Error: cannot allocate vector of size 572.2 Mb # Can't go smaller anymore
> rm(list=ls(all=TRUE))
> a = matrix(NA, 3500000, 60) # Now it works
> b = matrix(NA, 3500000, 60)
Error: cannot allocate vector of size 801.1 Mb # But that is all there is room for

Entiendo que esto está relacionado con la dificultad de obtener bloques contiguos de memoria (desde aquí ):

Los mensajes de error que comienzan no pueden asignar el vector de tamaño indican que no se pudo obtener memoria, ya sea porque el tamaño excedió el límite de espacio de direcciones para un proceso o, más probablemente, porque el sistema no pudo proporcionar la memoria. Tenga en cuenta que en una compilación de 32 bits puede haber suficiente memoria libre disponible, pero no un bloque contiguo de espacio de direcciones lo suficientemente grande como para asignarlo.

¿Cómo puedo evitar esto? Mi principal dificultad es que llego a cierto punto en mi script y R no puede asignar 200-300 Mb para un objeto ... Realmente no puedo preasignar el bloque porque necesito la memoria para otro procesamiento. Esto sucede incluso cuando elimino diligentemente objetos innecesarios.

EDITAR: Sí, lo siento: Windows XP SP3, 4 Gb de RAM, R 2.12.0:

> sessionInfo()
R version 2.12.0 (2010-10-15)
Platform: i386-pc-mingw32/i386 (32-bit)

locale:
[1] LC_COLLATE=English_Caribbean.1252  LC_CTYPE=English_Caribbean.1252   
[3] LC_MONETARY=English_Caribbean.1252 LC_NUMERIC=C                      
[5] LC_TIME=English_Caribbean.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
Benjamín
fuente
Intente usar 'gratis' para desasignar la memoria de otro proceso no utilizado.
Manoel Galdino
55
@ Manoel Galdino: ¿Qué es 'gratis'? ¿Una función R?
Benjamin
3
@Manoel: en R, la tarea de liberar memoria la maneja el recolector de basura, no el usuario. Si trabaja en el nivel C, uno puede hacerlo manualmente Callocy con Freememoria, pero sospecho que esto no es lo que Benjamin está haciendo.
Sharpie
En la biblioteca XML puedes usar gratis. De la documentación: "Esta función genérica está disponible para liberar explícitamente la memoria asociada con el objeto dado. Está destinada para su uso en objetos de puntero externos que no tienen una función / rutina de finalizador automático que limpia la memoria utilizada por el objeto nativo ".
Manoel Galdino

Respuestas:

78

Considere si realmente necesita todos estos datos explícitamente, o ¿puede la matriz ser escasa? Hay un buen soporte en R (vea el Matrixpaquete, por ejemplo) para matrices dispersas.

Mantenga todos los demás procesos y objetos en R al mínimo cuando necesite hacer objetos de este tamaño. Úselo gc()para borrar la memoria ahora no utilizada o, mejor, solo cree el objeto que necesita en una sesión .

Si lo anterior no puede ayudar, obtenga una máquina de 64 bits con tanta RAM como pueda, e instale R. de 64 bits

Si no puede hacerlo, hay muchos servicios en línea para la informática remota.

Si no puede hacer eso, las herramientas de mapeo de memoria como el paquete ff(o bigmemorycomo Sascha menciona) lo ayudarán a construir una nueva solución. En mi experiencia limitada ffes el paquete más avanzado, pero debe leer el High Performance Computingtema en Vistas de tareas CRAN.

mdsumner
fuente
1
La tarea es la clasificación de imágenes, con randomForest. Necesito tener una matriz de datos de entrenamiento (hasta 60 bandas) y entre 20,000 y 6,000,000 filas para alimentar al bosque aleatorio. Actualmente, llego al máximo a unas 150,000 filas porque necesito un bloque contiguo para contener el objeto randomForest resultante ... Por eso, bigmemory no ayuda, ya que randomForest requiere un objeto matriz.
Benjamin
¿Qué quiere decir con "solo crear el objeto que necesita en una sesión"?
Benjamin
solo cree 'a' una vez, si se equivoca la primera vez, inicie una nueva sesión
mdsumner
1
Agregaría que para los programas que contienen bucles grandes donde se realizan muchos cálculos, pero la salida es relativamente pequeña, puede ser más eficiente en la memoria llamar a la parte interna del bucle a través de Rscript (desde un script de BASH o Python) , y luego cotejar / agregar los resultados en un script diferente. De esa manera, la memoria se libera completamente después de cada iteración. Hay un poco de cálculo desperdiciado al volver a cargar / volver a calcular las variables pasadas al bucle, pero al menos puede solucionar el problema de la memoria.
Benjamin
54

Para los usuarios de Windows, lo siguiente me ayudó mucho a comprender algunas limitaciones de memoria:

  • antes de abrir R, abra el Monitor de recursos de Windows (Ctrl-Alt-Delete / Iniciar el Administrador de tareas / pestaña Rendimiento / haga clic en el botón inferior 'Monitor de recursos' / pestaña Memoria)
  • verá cuánta memoria RAM ya usamos antes de abrir R y por qué aplicaciones. En mi caso, se utilizan 1,6 GB del total de 4 GB. Así que solo podré obtener 2.4 GB para R, pero ahora viene lo peor ...
  • abra R y cree un conjunto de datos de 1.5 GB, luego reduzca su tamaño a 0.5 GB, el Monitor de recursos muestra que mi RAM se usa en casi el 95%.
  • uso gc()para hacer la recolección de basura => funciona, puedo ver que el uso de memoria se reduce a 2 GB

ingrese la descripción de la imagen aquí

Consejos adicionales que funcionan en mi máquina:

  • prepare las funciones, guárdelas como un archivo RData, cierre R, vuelva a abrir R y cargue las funciones del tren. El Administrador de recursos generalmente muestra un menor uso de memoria, lo que significa que incluso gc () no recupera toda la memoria posible y el cierre / reapertura de R funciona mejor para comenzar con la memoria máxima disponible .
  • el otro truco es cargar solo el conjunto de trenes para el entrenamiento (no cargue el conjunto de prueba, que generalmente puede ser la mitad del tamaño del conjunto de trenes). La fase de entrenamiento puede usar la memoria al máximo (100%), por lo que cualquier cosa disponible es útil. Todo esto es tomar con un grano de sal mientras estoy experimentando con los límites de memoria R.
Timothée HENRY
fuente
9
R hace la recolección de basura solo, gc()es solo una ilusión. Comprobar el Administrador de tareas es solo una operación muy básica de Windows. El único consejo con el que estoy de acuerdo es guardar en formato .RData
David Arenburg
3
@DavidArenburg gc () es una ilusión? Eso significaría que la imagen que tengo arriba que muestra la caída del uso de memoria es una ilusión. Creo que estás equivocado, pero podría estar equivocado.
Timothée HENRY
44
No quise decir que eso gc()no funciona. Solo quiero decir que R lo hace automáticamente, por lo que no necesita hacerlo manualmente. Ver aquí
David Arenburg
2
@DavidArenburg Puedo decirle con certeza que la caída del uso de memoria en la imagen de arriba se debe al comando gc (). No creo que el documento al que apunta sea correcto, al menos no para mi configuración (Windows, R versión 3.1.0 (2014-04-10) Plataforma: i386-w64-mingw32 / i386 (32 bits)).
Timothée HENRY
15
Ok, por ultima vez. gc() ¿Funciona ? Simplemente no necesita usarlo porque R lo hace internamente
David Arenburg
14

La forma más sencilla de eludir esta limitación es cambiar a 64 bits R.

David Heffernan
fuente
25
Eso no es una cura en general, he cambiado, y ahora lo he hecho Error: cannot allocate vector of size ... Gb(pero sí, tengo muchos datos).
om-nom-nom
2
Tal vez no sea una cura, pero ayuda mucho. Simplemente cargue en la RAM y siga aumentando la memoria. Limit (). O tal vez piense en particionar / muestrear sus datos.
random_forest_fanatic
Si tiene problemas incluso en 64 bits, que es esencialmente ilimitado, probablemente sea más que tratar de asignar algo realmente masivo. ¿Ha calculado, en teoría, qué tan grande debe ser el vector? De lo contrario, podría ser que su computadora necesita más RAM, pero solo hay una cantidad que puede tener.
hangmanwa7id
Es bueno probar las soluciones simples como esta antes de más soluciones cabeza a pared. Gracias.
Nova
Además, esto no es exclusivamente un problema con Windows. Actualmente estoy corriendo en Ubuntu, R de 64 bits, usando Matrix, y tengo dificultades para manipular un objeto Matrix 20048 x 96448.
12

Encontré un problema similar y usé 2 unidades flash como 'ReadyBoost'. Las dos unidades dieron un impulso adicional de 8GB de memoria (para caché) y resolvió el problema y también aumentó la velocidad del sistema en su conjunto. Para usar Readyboost, haga clic derecho en la unidad, vaya a propiedades y seleccione 'ReadyBoost' y seleccione el botón de opción 'usar este dispositivo' y haga clic en Aplicar o Aceptar para configurar.

Kwaku Damoah
fuente
11

Seguí a la página de ayuda de memor.limit y descubrí que en mi computadora R por defecto puede usar hasta ~ 1.5 GB de RAM y que el usuario puede aumentar este límite. Usando el siguiente código,

>memory.limit()
[1] 1535.875
> memory.limit(size=1800)

Me ayudó a resolver mi problema.

Rajib Kumar De
fuente
1
¿Por qué se rechaza esto? claro, es un enfoque peligroso, pero a menudo puede ayudar si solo se necesita asignar un poco más de memoria a la sesión para que funcione.
Jeppe Olsen
3
Esta es solo una solución específica de Windows
Jinhua Wang
9

Si está ejecutando su script en un entorno Linux, puede usar este comando:

bsub -q server_name -R "rusage[mem=requested_memory]" "Rscript script_name.R"

y el servidor asignará la memoria solicitada por usted (de acuerdo con los límites del servidor, pero con un buen servidor, se pueden usar enormes archivos)

nurit
fuente
1
¿Puedo usar esto en una instancia de Amazon EC2? Si es así, ¿qué pongo en lugar de server_name? Me encuentro cannot allocate vector size...con esto tratando de hacer una gran matriz de términos y documentos en un AMI y no puedo entender por qué no tiene suficiente memoria o cuánto más necesito alquilar. ¡Gracias!
seth127
Soy principiante de Ubuntu y uso Rstudio en él. Tengo 16 GB de RAM. ¿Cómo aplico el proceso que muestra en la respuesta? Gracias
runjumpfly
3

El método de guardar / cargar mencionado anteriormente funciona para mí. No estoy seguro de cómo / si gc()desfragmenta la memoria, pero esto parece funcionar.

# defrag memory 
save.image(file="temp.RData")
rm(list=ls())
load(file="temp.RData")
Simon Woodward
fuente