这个“丢失”的内存很大一部分可能是由于内存碎片。随着Matlab在会话过程中分配和释放数组,内存被分解成更小的区域,并且在Matlab和底层C级别的内存管理器中,有些内存会被浪费掉。开销不被计算为由Matlab使用,因为它不用于保存M代码数组值。一些内存也可能由Matlab加载额外的M文件和库,分配内部缓冲区或结构,或者通过在Matlab的嵌入式JVM中扩展Java堆来消耗。这个是正常的。在完成一些工作之后,Matlab将不会像在新的会话中那样获得尽可能多的内存。 AFAIK,一旦发生低级碎片,除了重新启动Matlab之外,没有什么可以做到的。分配大量小阵列可加速碎片。如果使用大型单元或大型对象数组,有时会发生这种情况。因此,如果遇到问题,您可能需要通过将工作分解为更小的块,减少小区使用等来降低功能中的峰值内存使用量。如果MAT文件中有大的cellstr数组,则将它们转换为char。分配的“高水位”是支配碎片的因素,因此如果您可以将数据集分成更小的块,则可以将其放入更少的内存中。
在您的功能中,清除尽可能多的从一个MAT文件进入下一个之前。隐式做到这一点的一种方法是将每个文件处理移动到一个子功能中,如果它目前正坐在主功能的循环中。
为了帮助调试,请执行“dbstop if all error”,这将由OOM触发。从那里,您可以使用whos和调试器来查明当您耗尽内存时正在占用的空间。这可能会揭示需要清理的临时变量,或者提出分块工作的方法。
如果您想尝试查看哪些碎片看起来像以及它如何影响memory()的输出,下面是一个只会创建一些碎片的函数。
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在我的机器上1KB块再现一个你所看到的大小我的Win32的机器上“损失”。
>> 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没有你尝试调用'pack'事后http://www.mathworks.com/access/helpdesk/help/techdoc/ref/pack.html – Amro 2010-07-21 17:45:13
包()只是重新安排Matlab的数组,其目前分配。由于已释放数组的剩余部分,它没有解决这种较低级别的碎片问题,并且在fragmem()例子之后影响可以忽略不计。 (至少在我使用的Windows上)。顺便说一句,Matlab的doco真的不会谈论这种较低级别的碎片;我在写什么,我从外部接口doco推断出来,并尝试使用Matlab和C.Catatat emptor。 – 2010-07-21 18:34:02
“为了帮助调试,请执行”dbstop if all error“,这将由OOM触发。从那里,您可以使用whos和调试器来查找当您耗尽内存时空间正在占用的位置。揭示需要清理的临时变量,或者提出分块工作的方法。“ 有趣的是,当我用完内存时,工作区很干净。上面的功能真的减少了可用内存,但没有在工作区中有很多变量... 这是一种讨厌有足够的内存..原则.. – Thomas 2010-07-22 08:26:34