Main Content

Resolver errores de memoria insuficiente

Problema

Cuando su código opera en grandes cantidades de datos o no utiliza la memoria de manera eficiente, MATLAB® podría producir un error en respuesta a un tamaño de arreglo excesivo, o bien podría quedarse sin memoria. MATLAB cuenta con protección integrada frente a la creación de arreglos demasiado grandes. Por ejemplo, este código resulta en un error, porque MATLAB no puede crear un arreglo con la cantidad de elementos solicitada.

A = rand(1e9);
Requested array exceeds the maximum possible variable size.

De forma predeterminada, MATLAB puede utilizar hasta el 100% de la RAM (sin incluir la memoria virtual) de su ordenador para asignar memoria para los arreglos y, si un arreglo supera dicho umbral, MATLAB devuelve un error. Por ejemplo, este código trata de crear un arreglo con un tamaño que excede el límite de tamaño máximo del arreglo.

B = rand(1e6);
Requested 1000000x1000000 (7450.6GB) array exceeds maximum array size preference (63.7GB). This might cause MATLAB to become
unresponsive.

Si desactiva el límite de tamaño del arreglo en MATLAB Workspace Preferences y trata de crear un arreglo excesivamente grande, podría provocar que MATLAB se quede sin memoria, o bien MATLAB o incluso su ordenador podrían dejar de responder debido a la excesiva paginación de la memoria (es decir, movimiento de páginas de memoria entre la RAM y el disco).

B = rand(1e6);
Out of memory.

Posibles soluciones

Independientemente del motivo de quedarse sin memoria, MATLAB ofrece varias soluciones dependiendo de su situación y sus objetivos. Por ejemplo, puede mejorar la forma en que su código utiliza la memoria; aprovechar estructuras de datos especializadas, como almacenes de datos y arreglos altos; sacar provecho a recursos agrupados en un cluster de ordenadores, o realizar ajustes en la configuración y las preferencias.

Nota

Las soluciones presentadas aquí son específicas para MATLAB. Para optimizar el rendimiento de la memoria en todo el sistema, considere la opción de agregar más memoria física (RAM) a su ordenador o efectuar ajustes en el sistema operativo.

Borrar las variables cuando dejan de ser necesarias

Borre las variables regularmente cuando dejen de ser necesarias. Para borrar elementos de la memoria, utilice la función clear.

AntesDespués
A = rand(1e4);
disp(max(A,[],"all"))
B = rand(1e4);
A = rand(1e4);
disp(max(A,[],"all"))
clear A
B = rand(1e4);

Para obtener más información, consulte Strategies for Efficient Use of Memory.

Usar el almacenamiento de datos adecuado

Los requisitos de la memoria difieren para tipos de datos de MATLAB. Puede reducir la cantidad de memoria que utiliza su código empleando el tipo de datos y el almacenamiento adecuados. Para obtener más información acerca de las soluciones de esta sección, consulte Strategies for Efficient Use of Memory.

Usar la clase numérica adecuada.  La clase numérica que debe utilizar depende de las acciones que pretenda realizar. En MATLAB, double es el tipo de datos numéricos predeterminado y proporciona la precisión suficiente para la mayoría de las tareas computacionales:

  • Si desea realizar operaciones matemáticas complicadas, como álgebra lineal, utilice números de punto flotante ya sea en formato de doble precisión (double) o en formato de precisión simple (single). Los números de tipo single requieren menos memoria que los números de tipo double, aunque también se representan con menos precisión.

  • Si tan solo necesita realizar operaciones aritméticas sencillas y representa los datos originales como enteros, utilice las clases de enteros de MATLAB.

Clase (tipos de datos)BytesOperaciones admitidas
single4Mayoría de operaciones matemáticas
double8Todas las operaciones matemáticas
logical1Operaciones condicionales/lógicas
int8, uint81Operaciones aritméticas y algunas funciones sencillas
int16, uint162Operaciones aritméticas y algunas funciones sencillas
int32, uint324Operaciones aritméticas y algunas funciones sencillas
int64, uint648Operaciones aritméticas y algunas funciones sencillas

Reducir la cantidad de carga al almacenar datos.  Cuando crea un arreglo numérico o de caracteres, MATLAB asigna un bloque de memoria para almacenar los datos del arreglo. MATLAB también almacena información acerca de los datos del arreglo, como su clase y sus dimensiones, en un pequeño bloque independiente de memoria llamado encabezado. Como los arreglos numéricos y de caracteres tienen la menor carga, utilícelos siempre que sea posible. Utilice otras estructuras de datos solo para datos que sean demasiado complejos como para almacenarlos en un arreglo simple.

Para estructuras y arreglos de celdas, MATLAB crea un encabezado no solo para el arreglo, sino también para cada campo de la estructura o cada celda del arreglo. Por lo tanto, la cantidad de memoria necesaria para almacenar una estructura o un arreglo de celdas dependerá no solo de cuántos datos albergue, sino también de cómo se haya construido. Así pues, los arreglos de celdas con muchos elementos pequeños o estructuras con muchos campos que contienen poco contenido tienen una gran carga y se deben evitar.

AntesDespués
% S has 15,000 fields (3 fields per array element)
for i = 1:100
    for j = 1:50
        S(i,j).R = 0;  % Each field contains a numeric scalar
        S(i,j).G = 0;
        S(i,j).B = 0;
    end
end
% S has 3 fields 
S.R = zeros(100,50);  % Each field contains a numeric array
S.G = zeros(100,50);
S.B = zeros(100,50);

Dispersar arreglos siempre que sea posible.  Es recomendable almacenar matrices con pocos elementos distintos de cero usando el almacenamiento disperso. Cuando una matriz llena tiene pocos elementos distintos de cero, convertir la matriz a almacenamiento disperso suele mejorar el uso de la memoria y los tiempos de ejecución de código. MATLAB cuenta con varias funciones compatibles con el almacenamiento disperso. Por ejemplo, puede utilizar la función speye para crear una matriz identidad dispersa.

AntesDespués
I = eye(1000);
I = speye(1000);

Importar datos empleando la clase de MATLAB adecuada.  Al leer datos de un archivo binario con fread, un error habitual es especificar solo la clase de datos del archivo y no la clase de datos que MATLAB usa cuando está en el área de trabajo. Si no especifica la clase de datos en la memoria, MATLAB utiliza double incluso aunque lea valores de 8 bits.

AntesDespués
fileID = fopen("large_file_of_uint8s.bin","r"); 
A = fread(fileID,1e3,"uint8"); 
fileID = fopen("large_file_of_uint8s.bin","r"); 
A = fread(fileID,1e3,"uint8=>uint8"); 

Evitar copias innecesarias de los datos

Para mejorar el uso de la memoria y la velocidad de ejecución, asegúrese de que su código no resulte en copias innecesarias de datos. Para obtener más información acerca de las soluciones de esta sección, consulte Avoid Unnecessary Copies of Data y Strategies for Efficient Use of Memory.

Evitar crear arreglos temporales.  Evite crear arreglos temporales cuando no sea necesario. Por ejemplo, en lugar de crear un arreglo de ceros como variable temporal y, a continuación, pasar esa variable a una función, utilice un comando para realizar ambas operaciones.

AntesDespués
A = zeros(1e6,1);
As = single(A);
As = zeros(1e6,1,"single");

Asignar memoria previamente.  Cuando trabaja con grandes conjuntos de datos, cambiar constantemente el tamaño de los arreglos podría provocar que el programa se quede sin memoria. Si amplía un arreglo más allá de la memoria contigua disponible de su ubicación original, MATLAB tiene que hacer una copia del arreglo y trasladarla a un bloque de memoria con espacio suficiente. Durante este proceso, hay dos copias del arreglo original en la memoria. Puede mejorar el uso de la memoria y la ejecución de código preasignando la máxima cantidad de espacio necesario para el arreglo. Para obtener más información, consulte Preasignación.

AntesDespués
x = 0;
for k = 2:1000000
   x(k) = x(k-1) + 5;
end
x = zeros(1,1000000);
for k = 2:1000000
   x(k) = x(k-1) + 5;
end

Usar funciones anidadas para pasar menos argumentos.  Al llamar a una función, MATLAB suele hacer una copia temporal de la variable en el área de trabajo del autor de la llamada si la función modifica su valor. MATLAB aplica varias técnicas para evitar tener que hacer copias innecesarias, si bien evitar una copia temporal de una variable de entrada no siempre es posible.

Una manera de evitar las copias temporales en las llamadas a funciones es usar las funciones anidadas. Una función anidada comparte el área de trabajo de las funciones exteriores, de forma que no es necesario que pase una copia de las variables en la llamada a la función. Para obtener más información, consulte Nested Functions.

Cargar solo los datos que se necesiten

Una forma de solucionar los problemas de memoria es importar en MATLAB solo tantos conjuntos de datos grandes como necesite para el problema que está intentando resolver. El tamaño del conjunto de datos no suele ser un problema al importar desde fuentes como una base de datos, donde puede buscar explícitamente elementos que coinciden con una consulta. No obstante, es un problema frecuente al cargar grandes archivos de texto plano o binarios.

La función datastore le permite trabajar con grandes conjuntos de datos de forma progresiva. Los almacenes de datos son útiles siempre que se desee cargar en la memoria únicamente algunas porciones de un conjunto de datos a la vez.

Para crear un almacén de datos, es necesario indicar el nombre de un archivo o directorio que contenga una recopilación de archivos con un formato similar. Por ejemplo, con un único archivo, utilice lo siguiente.

ds = datastore("path/to/file.csv");
O con una recopilación de archivos en una carpeta, utilice lo siguiente.
ds = datastore("path/to/folder/");
También puede utilizar el carácter comodín * para seleccionar todos los archivos de un tipo específico.
ds = datastore("path/to/*.csv");
Los almacenes de datos admiten una gran variedad de formatos de archivo (datos tabulares, imágenes, hojas de cálculo, etc.). Para obtener más información, consulte Select Datastore for File Format or Application.

Aparte de los almacenes de datos, MATLAB también tiene otras funciones para cargar partes de archivos. En esta tabla se resumen las funciones por el tipo de archivos en los que operan.

Tipo de archivoCarga parcial
Archivo MAT

Cargue parte de una variable indexando en un objeto que cree con la función matfile. Para obtener más información, consulte Guardar y cargar partes de variables en archivos MAT.

Texto

Utilice la función textscan para acceder a partes de un archivo de texto grande leyendo solo las columnas y filas seleccionadas. Si especifica el número de filas o un número de formato de repetición con textscan, MATLAB calcula de antemano la cantidad exacta de memoria necesaria.

Binario

Puede utilizar las funciones E/S de archivos binarios de bajo nivel, como fread, para acceder a partes de cualquier archivo que tenga un formato conocido. Para los archivos binarios de formato desconocido, intente usar la aplicación de memoria con la función memmapfile.

Imagen, audio, vídeo y HDF

Muchas de las funciones de MATLAB que admiten cargar desde estos tipos de archivos le permiten seleccionar porciones de los datos que se han de leer. Para obtener más información, consulte las páginas de referencia de las funciones enumeradas en Supported File Formats for Import and Export.

Usar arreglos altos

Los arreglos altos le ayudan a trabajar con conjuntos de datos demasiado grandes como para caber en la memoria. MATLAB trabaja con pequeños bloques de datos a la vez, gestionando automáticamente toda la fragmentación y el procesamiento de los datos en segundo plano. Hay dos formas principales de aprovechar los arreglos altos:

  • Si tiene un arreglo grande que cabe en la memoria, pero se queda sin memoria cuando intenta realizar cálculos, puede arrojar el arreglo a un arreglo alto.

    t = tall(A);
    Este método le permite trabajar con grandes arreglos que pueden caber en la memoria, pero que consumen demasiada memoria para poder realizar copias de los datos durante los cálculos. Por ejemplo, si tiene 8 GB de RAM y una matriz de 5 GB, arrojar la matriz a un arreglo alto le permite realizar cálculos en la matriz sin quedarse sin memoria. Consulte tall para ver un ejemplo de este uso.

  • Si tiene datos basados en archivos o carpetas, puede crear un almacén de datos y, después, crear un arreglo alto además del almacén de datos.

    ds = datastore("path/to/file.csv");
    t = tall(ds);
    Este método le proporciona toda la potencia de los arreglos altos en MATLAB. Los datos pueden tener cualquier número de filas y MATLAB no se queda sin memoria. Además, puesto que datastore funciona con ubicaciones de datos locales y remotas, los datos con los que trabaja no tienen que estar en el ordenador que utiliza para analizarlos. Para obtener más información, consulte Trabajar con datos remotos.

Para obtener más información sobre el acceso a arreglos altos, consulte Arreglos altos para datos con memoria insuficiente.

Aprovechar la memoria de varias máquinas

Si tiene un cluster de ordenadores, puede utilizar arreglos distribuidos (requiere Parallel Computing Toolbox™) para realizar cálculos con la memoria combinada de todas las máquinas del cluster. Dependiendo de cómo entren los datos en la memoria, hay formas diferentes de dividir los datos entre workers de una agrupación paralela. Para obtener más información, consulte Distributing Arrays to Parallel Workers (Parallel Computing Toolbox).

Ajustar la configuración y las preferencias

Por lo general, reescribir código es la forma más eficaz de mejorar el rendimiento de la memoria. Sin embargo, si no puede hacer cambios en el código, estas soluciones podrían facilitarle la cantidad necesaria de memoria.

Iniciar MATLAB con la máquina virtual de Java o reducir el tamaño del montón de Java.  Tanto si inicia MATLAB sin la máquina virtual de Java® (JVM™) como si reduce el tamaño del montón de Java, puede aumentar la memoria disponible en el área de trabajo. Para iniciar MATLAB sin JVM, utilice la opción de la línea de comandos -nojvm. Para obtener información sobre cómo reducir el tamaño del montón de Java, consulte Java Heap Memory Preferences.

Utilizar -nojvm conlleva una penalización por la que pierde varias funcionalidades que se basan en JVM, como las herramientas de escritorio y las gráficas. Iniciar MATLAB con la opción -nodesktop no ahorra una cantidad significativa de memoria.

Ajustar el límite de tamaño del arreglo.  Si se encuentra con un error que indica que el tamaño del arreglo supera la preferencia de tamaño máximo del arreglo, puede ajustar este límite de tamaño del arreglo en MATLAB. Para obtener más información sobre cómo ajustar el límite de tamaño del arreglo, consulte Workspace and Variable Preferences. Esta solución es útil solo si el arreglo que desea crear supera el límite de tamaño máximo actual, pero no es tan grande como para no caber en la memoria. Si desactiva el límite de tamaño del arreglo y trata de crear un arreglo excesivamente grande, podría provocar que MATLAB se quede sin memoria, o bien MATLAB o incluso su ordenador podrían dejar de responder debido a la excesiva paginación de la memoria.

Consulte también

| | |

Temas relacionados