2010-07-21 13 views
10

Tengo algunos problemas con la gestión de memoria en Matlab. Finalmente, esto conduce a que no haya suficiente memoria libre y un error. Intenté localizar el problema y encontré una "característica" interesante: de alguna manera, pierdo la Memoria libre en Matlab.Matlab: la memoria libre se pierde después de llamar a una función

hago lo siguiente:
1) Comience Matlab
2) escribiendo "memoria" me sale: Máximo posible matriz: 1293 MB, memoria disponible para todas las matrices: 1456 mb
3) Voy a llamar a una función. La función es bastante larga, por lo que es difícil pegarla aquí. Pero básicamente carga 5 ca. Archivos de tapete de 300 mb (secuencialmente), selecciona algunos valores y los devuelve. La matriz devuelta es ca. 1,2MB (4650x35 doble)
4) borro todas las variables en el espacio de trabajo ("Borrar todos")
5) escribiendo "memoria" me sale: Máximo amplia posible: 759 MB, memoria disponible para todas las matrices: 1029 mb

Si repito los pasos 3) a 5) los números de memoria son constantes.

¿Qué pasa aquí? ¿Dónde pierdo los 400 mb de espacio libre? La memoria utilizada por Matlab es constante en alrededor de 330mb.

¿Alguien tiene alguna idea de lo que está mal aquí? ¿O es algo totalmente natural, pero lo extraño?

Gracias
Thomas

PD: Yo uso de Matlab 2010a y Win 7 Pro 32 bits.

Respuesta

16

Una buena parte de esta memoria "perdida" se debe probablemente a la fragmentación de la memoria. Como Matlab asigna y libera matrices en el transcurso de una sesión, la memoria se divide en áreas más pequeñas, y algunas se pierden en la administración general en el administrador de memoria, tanto en Matlab como en los niveles C subyacentes. La sobrecarga no es contada como "usada" por Matlab porque no está siendo utilizada para contener valores de matriz de código M. Parte de la memoria también puede ser consumida por Matlab cargando archivos M y bibliotecas adicionales, asignando búferes o estructuras internas, o por la expansión del almacenamiento dinámico de Java en la JVM integrada de Matlab. Esto es normal. Después de hacer un poco de trabajo, Matlab no tendrá tanta memoria disponible como lo hizo en una nueva sesión.

AFAIK, una vez que se produce la fragmentación de bajo nivel, no hay nada que se pueda hacer para eliminarlo aparte de reiniciar Matlab. La asignación de muchos arreglos pequeños puede acelerar la fragmentación. Esto sucede a veces si usa celdas grandes o grandes conjuntos de objetos. Por lo tanto, si tiene problemas, es posible que deba reducir el uso máximo de la memoria en la función dividiendo el trabajo en fragmentos más pequeños, reduciendo el uso de la celda, y así sucesivamente. Y si tiene matrices cell grandes en los archivos MAT, conviértelos en char. La "marca máxima" de asignación es lo que rige la fragmentación, por lo que si puede dividir su conjunto de datos en fragmentos más pequeños, puede caber en menos memoria.

Dentro de su función, borre todo lo que pueda de un archivo MAT antes de pasar al siguiente. Una forma de hacer esto implícitamente es mover el procesamiento por archivo a una subfunción si está actualmente en un bucle en su función principal.

Para ayudar a depurar, realice un "dbstop if all error", que será activado por OOM. Desde allí, puede usar whos y el depurador para averiguar dónde se está ocupando el espacio cuando agota la memoria. Eso podría revelar variables tempranas que deben ser limpiadas, o sugerir formas de fragmentar el trabajo.

Si desea experimentar para ver qué aspecto tiene la fragmentación y cómo afecta la salida de memory(), aquí hay una función que solo creará cierta fragmentación.

function fragmem(nbytes, chunksize) 
%FRAGMEM Fragment the Matlab session's memory 
if nargin < 2; chunksize = 1*2^10; end 

nbytes = nbytes - rem(nbytes, chunksize); 

nsteps = 100; % to make initial input relatively small 
c = cell([1 nsteps]); 
stepsize = nbytes/nsteps; 
chunksperstep = ceil(stepsize/chunksize); 
fprintf('Fragmenting %d MB memory into %d KB chunks (%d steps of %d chunks)\n',... 
    round(nbytes/2^20), round(chunksize/2^10), nsteps, chunksperstep); 

x = zeros([1 chunksperstep * chunksize], 'uint8'); 
colsizes = repmat(chunksize, [1 chunksperstep]); 
for i = 1:nsteps 
    c{i} = mat2cell(x, 1, colsizes); 
end 

Fragging 300 MB en trozos de 1 KB en mi máquina reproduce una "pérdida" en mi máquina Win32 del tamaño que se está viendo.

>> memory 
Maximum possible array:   1384 MB (1.451e+009 bytes) * 
Memory available for all arrays: 1552 MB (1.627e+009 bytes) ** 
Memory used by MATLAB:    235 MB (2.463e+008 bytes) 
Physical Memory (RAM):    3311 MB (3.472e+009 bytes) 

>> fragmem(300*2^20) 
Fragmenting 300 MB memory into 1 KB chunks (100 steps of 3072 chunks) 
>> memory 
Maximum possible array:   1009 MB (1.059e+009 bytes) * 
Memory available for all arrays: 1175 MB (1.232e+009 bytes) ** 
Memory used by MATLAB:    257 MB (2.691e+008 bytes) 
Physical Memory (RAM):    3311 MB (3.472e+009 bytes) 

>> 
+0

+1 hicieron intenta llamar 'pak después http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro

+2

Pack() sólo se reorganiza matrices que son Matlab actualmente asignado. No aborda esta fragmentación de nivel inferior debido al residuo de las matrices ya liberadas, y tiene un efecto insignificante después del ejemplo de fragmem(). (Al menos en Windows, que uso). Por cierto, el doco de Matlab realmente no habla sobre esta fragmentación de nivel inferior; lo que estoy escribiendo, lo he deducido de las interfaces externas doco y experimentando con Matlab y C. Caveat Emptor. –

+0

"para ayudar a depurar, hacer un 'dbstop si todo error', que conseguirá provocada por el OOM. A partir de ahí, se puede utilizar whos y el depurador para localizar el origen del espacio está siendo tomado cuando la memoria de escape. Así podría ocurrir, revele variables tempranas que necesitan ser limpiadas, o sugiera maneras de fragmentar el trabajo ". Curiosamente, el espacio de trabajo está limpio cuando me quedo sin memoria. La función anterior realmente reduce la memoria libre, pero sin tener muchos vars en el área de trabajo ... Es bastante molesto tener suficiente memoria RAM ... en principio ... – Thomas

Cuestiones relacionadas