2010-07-21 14 views
10

Ho alcuni problemi con la gestione della memoria in Matlab. Finalmente non porta abbastanza memoria libera e un errore. Ho cercato di individuare il problema e ho trovato una "caratteristica" interessante: in qualche modo ho perso memoria libera in Matlab.Matlab: la memoria libera si perde dopo aver chiamato una funzione

faccio la seguente:
1) Avviare Matlab
2) digitando "memoria" ottengo: massima gamma possibile: 1293 Mb, memoria disponibile per tutti gli array: 1456 mb
3) io chiamo un funzione. La funzione è piuttosto lunga, quindi è difficile incollarla qui. Ma in pratica si carica 5 ca. I file mat 300mb (in sequenza), selezionano alcuni valori e li restituiscono. La matrice restituita è ca. 1,2 MB (4650x35 doppio)
4) Cancella tutte le variabili nello spazio di lavoro ("cancella tutto")
5) digitando "memoria" ottengo: Array massimo possibile: 759 mb, Memoria disponibile per tutti gli array: 1029 mb

Se ripeto i passaggi 3) a 5) i numeri di memoria sono costanti.

Quindi cosa c'è di sbagliato qui? Dove posso perdere i 400mb di spazio libero? La memoria utilizzata da Matlab è costante a circa 330 mb.

Qualcuno ha qualche idea di cosa c'è che non va qui? O è qualcosa di totalmente naturale, ma mi manca ??

Grazie
Thomas

Ps: io uso Matlab 2010a e Win 7 pro 32bit.

risposta

16

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) 

>> 
+0

+1 ha fatto si tenta di chiamare 'pack' dopo http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro

+2

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. –

+0

"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

Problemi correlati