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)
>>
+1 hicieron intenta llamar 'pak después http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro
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. –
"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