Una buona parte di questa memoria "persa" è probabilmente dovuta alla frammentazione della memoria. Dato che Matlab alloca e libera gli array nel corso di una sessione, la memoria viene suddivisa in aree più piccole e alcuni vengono persi in overhead nel gestore della memoria, sia in Matlab che nei livelli C sottostanti. Il sovraccarico non viene conteggiato come "usato" da Matlab perché non viene utilizzato per contenere i valori dell'array M-code. Parte della memoria può essere consumata da Matlab caricando ulteriori M-file e librerie, allocando buffer o strutture interne, o espandendo l'heap Java nella JVM di Matlab. E 'normale. Dopo aver lavorato, Matlab non avrà più memoria disponibile come in una nuova sessione.
AFAIK, una volta che si verifica una frammentazione di basso livello, non c'è niente che puoi fare per eliminarlo dal riavvio di Matlab. L'allocazione di molti piccoli array può accelerare la frammentazione. Questo a volte succede se si usano celle grandi o grandi matrici di oggetti. Pertanto, se si verificano problemi, potrebbe essere necessario ridurre l'utilizzo della memoria di picco nella funzione suddividendo il lavoro in blocchi più piccoli, riducendo l'utilizzo della cella e così via. E se disponi di grandi array cellstr nei file MAT, convertili in char. Il "high water mark" di allocazione è ciò che governa la frammentazione, quindi se riesci a infrangere il tuo set di dati in blocchi più piccoli, puoi inserirlo in meno memoria.
All'interno della funzione, deselezionare il più possibile da un file MAT prima di passare a quello successivo. Un modo per farlo in modo implicito è spostare l'elaborazione per file in una sottofunzione se si trova attualmente in un ciclo nella funzione principale.
Per facilitare il debug, eseguire "dbstop se tutti gli errori", che verranno attivati dall'OOM. Da lì, puoi usare whos e il debugger per scoprire dove viene occupato lo spazio quando esaurisci la memoria. Ciò potrebbe rivelare variabili temporanee che devono essere ripulite, o suggerire modi di frammentare il lavoro.
Se vuoi sperimentare per vedere come appare la frammentazione e come influenza l'output di memoria(), ecco una funzione che creerà solo una frammentazione.
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 in blocchi da 1 KB sulla mia macchina riproduce una "perdita" sulla mia macchina win32 circa le dimensioni che stai vedendo.
>> 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 ha fatto si tenta di chiamare 'pack' dopo http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro
Pack() riorganizza solo le matrici che sono Matlab attualmente assegnato. Non affronta questa frammentazione di livello inferiore a causa del residuo di array già liberati e ha un effetto trascurabile dopo l'esempio fragmem(). (Almeno su Windows, che uso.) A proposito, la Matlab doco non parla davvero di questa frammentazione di livello inferiore; quello che sto scrivendo, l'ho dedotto dall'interfaccia esterna doco e sperimentando con Matlab e C. Caveat emptor. –
"Per facilitare il debug, eseguire un comando" dbstop if all error ", che verrà attivato da OOM, da cui è possibile utilizzare whos e il debugger per scoprire dove viene occupato lo spazio quando si esaurisce la memoria. rivelare variabili temporali che devono essere ripulite o suggerire modi per frammentare il lavoro. " È interessante notare che l'area di lavoro è pulita quando esaurisco la memoria. La funzione sopra riduce veramente la memoria libera, ma senza avere molti oggetti nell'area di lavoro ... È piuttosto fastidioso avere abbastanza RAM ... in linea di principio .. – Thomas