MATLAB 实现了“延迟写入时复制”模型。让我用一个例子来解释。
首先,创建一个非常大的向量
x = ones(5*1e7,1);
现在,假设我们要创建另一个相同大小的向量:
y = ones(5*1e7,1);
在我的机器上,这将失败并出现以下错误
???记不清。键入 HELP MEMORY 作为您的选项。
我们知道y 将需要5*1e7*8 = 400000000 bytes ~ 381.47 MB(which x 也确认了这一点),但如果我们检查剩余的空闲连续内存量:
>> memory
Maximum possible array: 242 MB (2.540e+008 bytes) *
Memory available for all arrays: 965 MB (1.012e+009 bytes) **
Memory used by MATLAB: 820 MB (8.596e+008 bytes)
Physical Memory (RAM): 3070 MB (3.219e+009 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
我们可以看到它超过了可用的242 MB。
另一方面,如果你指定:
y = x;
它几乎会立即成功。这是因为 MATLAB 实际上并没有分配与x 相同大小的另一个内存块,而是创建了一个变量y,该变量与x 共享相同的基础数据(实际上,如果您再次调用memory,你会发现几乎没有区别)。
MATLAB 只会在其中一个变量发生变化时尝试制作数据的另一个副本,因此如果您尝试这个相当无辜的赋值语句:
y(1) = 99;
它会抛出一个错误,抱怨内存不足,我怀疑这就是你的情况......
编辑:
我能够通过以下示例重现该问题:
%# a large enough sparse matrix (you may need to adjust the size)
dist = sparse(1:3000000,1:3000000,1);
首先,让我们检查一下内存状态:
» whos
Name Size Bytes Class Attributes
dist 3000000x3000000 48000004 double sparse
» memory
Maximum possible array: 394 MB (4.132e+008 bytes) *
Memory available for all arrays: 1468 MB (1.539e+009 bytes) **
Memory used by MATLAB: 328 MB (3.440e+008 bytes)
Physical Memory (RAM): 3070 MB (3.219e+009 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
假设我们想对所有非零元素应用一个函数:
f = @(X) exp(-X.^2 ./ 2);
很奇怪,如果你尝试切片/分配,那么它会失败:
» dist(dist~=0) = f( dist(dist~=0) );
??? Maximum variable size allowed by the program is exceeded.
但是下面的赋值不会抛出错误:
[r,c,val] = find(dist);
dist = sparse(r, c, f(val));
我仍然没有解释为什么在第一种情况下会抛出错误,但也许以这种方式使用 FIND 函数可以解决您的问题...