Matlab:调用函数后可用内存丢失

Tho*_*mas 10 memory matlab

我在Matlab中遇到了一些内存管理问题.最后它导致没有足够的可用内存和错误.我试图找出问题并找到一个有趣的"功能":不知怎的,我在Matlab中松散了自由内存.

我执行以下操作:
1)启动Matlab
2)键入"memory"我得到:最大可能的数组:1293 mb,所有数组的内存可用:1456 mb
3)我将调用一个函数.功能相当长,因此很难将其粘贴到此处.但基本上它加载5 ca. 300mb mat文件(按顺序),选择一些值并返回它们.返回的矩阵是ca. 1,2mb(4650x35 double)
4)我清除工作区中的所有变量("全部清除")
5)键入"memory"我得到:最大可能的数组:759 mb,所有数组的内存可用:1029 mb

如果我重复步骤3)到5),则存储器编号是恒定的.

那么这里有什么问题?我在哪里可以放松400mb的免费空间?Matlab使用的内存不变,大约为330mb.

有没有人有一些想法在这里有什么问题?或者这是完全自然的东西,但我想念它?

谢谢
托马斯

Ps:我使用Matlab 2010a和Win 7 pro 32bit.

And*_*nke 16

这种"丢失"内存的很大一部分可能是由于内存碎片造成的.当Matlab在会话过程中分配和释放数组时,内存会被分解为更小的区域,并且在Matlab和底层C级别的内存管理器中,一些内存会丢失.开销不计入Matlab的"使用",因为它不用于保存M代码数组值.Matlab加载额外的M文件和库,分配内部缓冲区或结构,或者通过在Matlab的嵌入式JVM中扩展Java堆,也可以使用一些内存.这个是正常的.在完成一些工作后,Matlab将没有像在新会话中那样可用的内存.

AFAIK,一旦发生低级碎片,除了重新启动Matlab之外,没有什么可以消除它.分配大量小型阵列可以加速碎片化.如果使用大型单元或大型对象数组,有时会发生这种情况.因此,如果遇到问题,可能需要通过将工作分解为更小的块,减少单元使用量等来减少函数中的峰值内存使用量.如果MAT文件中有大型celltr数组,请将它们转换为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
Run Code Online (Sandbox Code Playgroud)

在我的机器上以1KB块的形式碎片300 MB会在我的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)

>> 
Run Code Online (Sandbox Code Playgroud)

  • Pack()只重新排列当前分配的Matlab数组.由于已经释放的数组的残留,它没有解决这种较低级别的碎片,并且在fragmem()示例之后具有可忽略的影响.(至少在我使用的Windows上.)顺便说一句,Matlab doco真的不会谈论这种低级别的碎片; 我正在写的,我从外部接口doco推断并尝试使用Matlab和C. Caveat emptor. (2认同)