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