2010-07-21 4 views
10

J'ai des problèmes avec la gestion de la mémoire dans Matlab. Finalement, cela ne conduit pas à une mémoire libre suffisante et à une erreur. J'ai essayé de localiser le problème et j'ai trouvé une "caractéristique" intéressante: D'une certaine façon, je perds de la mémoire libre dans Matlab.Matlab: La mémoire libre est perdue après l'appel d'une fonction

Je fais ce qui suit:
1) Lancer Matlab
2) en tapant "mémoire" je reçois: array possible maximum: 1293 Mo, mémoire disponible pour tous les tableaux: 1456 mb
3) Je vais appeler un fonction. La fonction est plutôt longue, il est donc difficile de la coller ici. Mais fondamentalement, il charge 5 ca. Les fichiers mat de 300mb (séquentiellement), sélectionne quelques valeurs et les renvoie. La matrice renvoyée est ca. 1,2Mb (4650x35 Double)
4) effacer toutes les variables dans l'espace de travail ("effacer")
5) en tapant "mémoire" je reçois: array possible maximum: 759 Mo, mémoire disponible pour tous les tableaux: 1029 mb

Si je répète les étapes 3) à 5), les numéros de mémoire sont constants.

Alors qu'est-ce qui ne va pas ici? Où puis-je perdre les 400 Mo d'espace libre? La mémoire utilisée par Matlab est constante à environ 330mb.

Est-ce que quelqu'un a des idées sur ce qui ne va pas ici? Ou est-ce quelque chose de totalement naturel, mais ça me manque?

Merci
Thomas

Ps: J'utilise Matlab 2010a et Win 7 Pro 32 bits.

Répondre

16

Une bonne partie de cette mémoire "perdue" est probablement due à la fragmentation de la mémoire. Au fur et à mesure que Matlab alloue et libère des tableaux au cours d'une session, la mémoire se décompose en zones plus petites et une partie est perdue dans le gestionnaire de mémoire, tant au niveau Matlab qu'au niveau C sous-jacent. Le surcoût n'est pas considéré comme "utilisé" par Matlab car il n'est pas utilisé pour contenir des valeurs de tableau de code M. De la mémoire peut également être utilisée par Matlab en chargeant des fichiers M et des bibliothèques supplémentaires, en allouant des tampons internes ou des structures, ou en développant le tas Java dans la JVM intégrée de Matlab. C'est normal. Après avoir travaillé, Matlab n'aura pas autant de mémoire disponible que lors d'une nouvelle session. AFAIK, une fois que la fragmentation de bas niveau se produit, il n'y a rien que vous puissiez faire pour l'éliminer en dehors du redémarrage de Matlab. Allouer beaucoup de petits tableaux peut accélérer la fragmentation. Cela arrive parfois si vous utilisez de grandes cellules ou de grands tableaux d'objets. Ainsi, si vous rencontrez des problèmes, vous devrez peut-être réduire votre utilisation de la mémoire de pointe dans la fonction en divisant le travail en plus petits morceaux, en réduisant l'utilisation des cellules, etc. Et si vous avez de grands tableaux de cellules dans les fichiers MAT, convertissez-les en char. La «marque d'eau haute» de l'allocation est ce qui gouverne la fragmentation, donc si vous pouvez diviser votre ensemble de données en plus petits morceaux, vous pouvez l'adapter en moins de mémoire.

À l'intérieur de votre fonction, effacez autant que possible d'un fichier MAT avant de passer au suivant. Une façon de le faire implicitement est de déplacer le traitement par fichier dans une sous-fonction s'il est actuellement placé dans une boucle de votre fonction principale.

Pour faciliter le débogage, faites un "dbstop if all error", qui sera déclenché par le MOO. À partir de là, vous pouvez utiliser whos et le débogueur pour savoir où l'espace est occupé lorsque vous videz la mémoire. Cela peut révéler des variables temporaires qui doivent être nettoyées ou suggérer des façons de découper le travail. Si vous souhaitez expérimenter pour voir à quoi ressemble la fragmentation et comment elle affecte la sortie de memory(), voici une fonction qui créera une certaine fragmentation.

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 Mo en morceaux sur 1KB ma machine reproduit une « perte » sur ma machine win32 de la taille que vous voyez.

>> 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 avez-vous essayé d'appeler 'pak' après http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro

+2

pack() ne réarrange tableaux Matlab qui sont actuellement attribué. Il n'aborde pas cette fragmentation de niveau inférieur en raison du résidu de tableaux déjà libérés, et a un effet négligeable après l'exemple de fragmem(). (Au moins sur Windows, que j'utilise.) BTW, le doco Matlab ne parle vraiment pas de cette fragmentation de niveau inférieur; ce que j'écris, j'ai déduit du document Interfaces externes et expérimenté avec Matlab et C. Caveat emptor. –

+0

"Pour aider au débogage, faites un" dbstop if all error ", qui sera déclenché par le MOO, à partir de là, vous pouvez utiliser whos et le débogueur pour savoir où l'espace est occupé lorsque vous utilisez la mémoire. révéler les variables temporaires qui doivent être nettoyées ou suggérer des façons de découper le travail. " Fait intéressant, l'espace de travail est propre lorsque je n'ai plus de mémoire. La fonction ci-dessus réduit vraiment la mémoire libre, mais sans avoir beaucoup de vars dans l'espace de travail ... C'est assez énervant d'avoir assez de RAM ... en principe .. – Thomas

Questions connexes