• 首页
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案
目录

matlab内存不足的6点解决措施

matlab内存不足的常见解决方法有:1. 升级内存2. 升级64位系统3. 增加虚拟内存4. 采用3GB开关启动系统等;除此以外,在弄清楚:Matlab是如何存储矩阵的?2、如何高效使用Memory?两个问题后,我们还可通过在命令行输入 pack 整理内存空间使用稀疏矩阵或将矩阵转化成稀疏形式 sparse等方法从根本上解决问题。

一、matlab内存不足的原因?如何查询?

如果你的系统是32位系统(进程最大支配2G空间,另外2G给系统进程了),在使用matlab 运行耗内存程序时候,会可能出现 out of memory 错误。这是因为matlab没有足够内存可以使用的缘故。解决的简单方法是加内存和升级为64位系统了,当然其他方法我们也将在后面详细介绍。

matlab具体能支持多大的数据呢?我们可以使用memory命令来查询。可以在matlab命令行输入 memory 看看你的系统的限制。

例如我的系统是:

memory
Maximum possible array:            1451 MB (1.521e+009 bytes) *    当前系统数组能占的最大内存
Memory available for all arrays:   1451 MB (1.521e+009 bytes) *    当前系统变量可被分配的空间
Memory used by MATLAB:              126 MB (1.320e+008 bytes)    已经使用的内存数量
Physical Memory (RAM):             2038 MB (2.137e+009 bytes)     系统物理内存数量

* Limited by System Memory (physical + swap file) available. 打星号表示受限于系统内存和交换空间的大小。

二、matlab内存不足的解决方法

当你写的 Matlab 程序跳出“Out of Memory”时,以下几点措施是需要优先考虑的解决方法:

1. 升级内存

2. 升级64位系统

3. 增加虚拟内存

4. 采用3GB开关启动系统

由于32位 Windows 操作系统的限制,每个进程只能使用非常多 2GB 的虚拟内存地址空间,因此 Matlab的可分配内存也受到相应的限制。Matlab 7.0.1 引进了新的内存管理机制,可以利用 Windows 的 3GB 开关,使用3GB 开关启动的 Windows 每个进程可以在多分配 1 GB 的虚拟地址空间。具体做法是:修改C盘根目录 boot.ini启动选项加上 /3G,例如:
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS=”Microsoft Windows XPProfessional” /noexecute=optin /fastdetect /3G

5. 如果必有必要,不要启动java虚拟机,采用matlab -nojvm启动 (在快捷方式属性里面的”…./matlab.exe”) 改为(”…../matlab.exe” – nojvm)

6. 关闭Matlab Server 控制面板-管理工具-服务,再找到matlabserver对应项,把启动类型的自动改为手动即可,matlab server作为后台服务可以在其它机器上通过网络调用此服务,进行计算任务。

7. Windows中字体、窗口等都是要占用系统资源的,所以在Matlab运行时尽量不要打开不用的窗口。

三、matlab内存不足问题的根本解决方法

除此以外,更关键的是需要弄清楚以下几个问题:

Matlab是如何存储矩阵的?

Matlab中矩阵是以Block,也就是块的形式存储的。也就是说,当Matlab在为即将存储的矩阵划分块时,如果没有相应大小的连续内存,即使实际内存没有被完全使用,它还是会报告“Outof Memory”。

如何高效使用Memory?

Matlab 中数组必须占用连续分配的内存段,当无法为新建的数组分配连续的内存段的时候,”Out of Memory”就会出现。在使用的过程中,由于存储单元的不断的被分配和清除,反复分配和释放数组会使内存被分割成不连续的区域,可用的连续内存段减少,很容易造成“Out of Memory”。因此当 Matlab 刚刚启动时其连续内存非常多,此时往往可以新建非常大的数组,这一点可以用命令feature(’memstats’)(在 7.0版本以上)看出。如果现实的最大连续内存段很小,但实际可用内存(非连续的)仍旧很多,则表明内存中碎片太多了。此时可以考虑用 pack命令,pack 命令的作用就是将所有内存中的数组写入硬盘,然后重新建立这些数组,以减少内存碎片。此外,在命令行或者程序中都可以使用clear 命令,随时减少不必要的内存。

因此,治本的方法如下:

1. 在命令行输入 pack 整理内存空间

当内存被分为很多碎片以后,其实本身可能有很大的空间,只是没有作构的连续空间即大的Block而已。如果此时Out ofMemory,此时使用pack命令可以很好的解决此问题。

2. 使用稀疏矩阵或将矩阵转化成稀疏形式 sparse

如果矩阵中有大量的0,较好存储成稀疏形式。稀疏形式的矩阵使用内存更少,执行时间更短。例如:000×1000的矩阵X,它2/3的元素为0,使用两种存储方法的比较:

Name
Size
Bytes
Class

X
1000×1000
8000000
double array

Y
1000×1000
4004000
double array (sparse)

3. 尽量避免产生大的瞬时变量,把没必要的变量clear掉或当它们不用的时候应该及时clear。

4. 减少变量,尽量的重复使用变量(跟不用的clear掉一个意思)。

5. 把有用的变量先save,后clear 掉,需要时再读出来。

下面介绍一下关于clear、save、load的特殊用法,这对在for或while等多重循环里出现out ofmemory非常有效。

for k =1:N    % N为循环次数
% ———————
    var0 = k; %获得变量var0                        
%———————-
    string = [Sprintf(‘var_%d’, k) ‘ = var0;’ ];
    eval_r(string);                                              % 等价于 var_k = var0;
    save(sprintf(‘var_%d.mat’, k), sprintf(‘var_%d’)); % 等价于 savevar_k.mat var_k
    clear(sprintf(‘var_%d’));                                  % 等价于 clear var_k
end

如果要读取刚才存取的变量var_k, (k = 1,2, …, N). 那么,可以使用如下用法:

for k = 1:N
      load(Sprintf(‘var_%d.mat’,k));    % 等价于 loadvar_k.mat    k = 1,2, …, N
end

另外,还有一些非常有用的用法。如果用清除刚才读取的变量 var_k, k = 1, 2, …, N

clear ‘-regexp”^var_’    % 清除所有以“ var_ ”开头的变量

还有很多关于save、clear、load等用法,具体help一下。

6. 使用单精度 single 短整数替代双精度 double

Matlab 默认的数字类型是双精度浮点数 (double),每个双浮点数占用 8个字节。对于一些整数操作来说,使用双浮点数显得很浪费。在 Matlab中可以在预先分配数组时指定使用的数字类型如以下命令:zero(10, 10, ‘uint8′)。对于浮点数,在很多精度要求不高的情况下,可以使用4个字节的单浮点数(single),可以减少一半的内存。关于单、双浮点数的精度对照如下,以便根据需要选择使用:

single: 精度 (1.1921e-007) 最大数 (3.4028e+038)

double: 精度 (2.2204e-016) 最大数 (1.7977e+308)

7. 为矩阵变量预制内存而不是动态分配

在动态分配的过程中,由于开始Matlab所用的Block随着矩阵的增大而连续的为此矩阵分配内存,但是由于Block的不连续性,很有可能最开始分配的Block不能满足存储的需要,Matlab只好移动此Block以找到更大的Block来存储,这样在移动的过程中不但占用了大量的时间,而且很有可能它找不到更大的块,导致Out ofMemory。而当你为矩阵变量预制内存时,Matlab会在计算开始前一次性找到最合适的Block,此时就不用为变量连续的分配内存。比较下面两个程序:

for k = 2:1000
    x(k) = x(k-1) + 5;
end

x = zeros(1, 1000);
for k = 2:1000
    x(k) = x(k-1) + 5;
end

显然,第二个更好!!!较好的方法是,在程序一开始就位所有大的矩阵变量预制存存储单元!!!

8. 尽量早的为大的矩阵变量预制内存

Matlab使用heap method管理内存。当在Matlabheap中没有足够的内存使用时,它会向系统请求内存。但是只要内存碎片可以存下当前的变量,Matlab会重新使用内存。比如:

a = rand(1e6,1);
b = rand(1e6,1);
使用大约15.4 MB RAM

c = rand(2.1e6,1);
使用近似16.4 MB RAM

a = rand(1e6,1);
b = rand(1e6,1);
clear
c = rand(2.1e6,1);
使用32.4 MB RAM

Matlab不能使用a、b被clear的空间,因为它们均小于2.1 MB,而同时它们也很可能是不连续的。较好的方法:

c = rand(2.1e6,1);
clear
a = rand(1e6,1);
b = rand(1e6,1);
使用16.4 MB RAM

9. 如果可行的话,将一个大的矩阵划分为几个小的矩阵,这样每一次使用的内存减少。

经过保存需要的变量,删除不必要的变量,运行pack命令,系统前后的内存占用情况有了很大改善:

这是清理之前:

>> memory
Maximum possiblearray:             15 MB (1.622e+007 bytes) *
Memory available for allarrays:    194MB (2.036e+008 bytes) **
Memory used byMATLAB:            1549 MB (1.624e+009 bytes)
Physical Memory(RAM):            4095 MB (4.294e+009 bytes)

*  Limited by contiguous virtual address spaceavailable.
** Limited by virtual address space available.

这是清理之后:

Maximum possiblearray:            252 MB (2.641e+008 bytes) *
Memory available for allarrays:    988MB (1.036e+009 bytes) **
Memory used byMATLAB:             762 MB (7.991e+008 bytes)
Physical Memory(RAM):            4095 MB (4.294e+009 bytes)

*  Limited by contiguous virtual address spaceavailable.
** Limited by virtual address space available.

相关文章