matlab out of memory产生原因和解决办法

来源:互联网 发布:c语言程序如何模块化 编辑:程序博客网 时间:2024/05/21 09:15
MATLAB out of memory产生原因及解决办法


查看内存使用情况命令:
>> system_dependent memstats


产生内存溢出的原因:
1、变量需要的存储空间超过了可用的内存空间
2、数据需要的存储空间,超过了内存中最大的可用连续存储空间
3、程序和问题求解方法的设计不周,导致内存溢出


在使用过程中,由于存储单元的不断的被分配和清除,内存会被分割成不连续的区域,很容易造成out of memory
解决办法:
1、为矩阵变量预置内存
在动态分配的过程中,由于开始MATLAB所用的block随着矩阵的增大而连续的为矩阵分配内存,
但是由于block的不连续性,很有可能最开始分配的block不能满足存储需要,MATLAB只好移
动此block以找到更大的block来存储,这样在移动过程中不但占用了大量的的时间,而且很有
可能找不到更大的块,导致out of memory。当为矩阵变量预置内存时,matlab会在计算开始前
一次性找到最合适的block,此时不用为变量连续的分配内存
例子:
(1)
for k = 2:1000
 x(k) = x(k-1)+5
end
(2)
x = zeros(1,1000);
for k = 2:1000
 x(k) = x(k-1)+5
end
方法(2)要优于(1)
2、尽量早的分配大的矩阵变量
MATLAB 使用heap method管理内存,当在MATLAB heap中没有足够的内存使用时,会向系统请求内存。
但是只要内存碎片可以存下当前的变量,MATLAB会重新使用内存,所以在大内存变量clear之后,新建
的小内存变量仍可以使用那部分内存空间,但相反的就不行了。比如:变量a 4M,b、c、d、e、分别占
用1M,如果a被clear以后定义bcde,则可以使用a的空间,如果clear b,c,d,e以后,假如这四个变量不是
连续的,那么a就不能使用它们释放的内存。
3、尽量避免产生大的瞬时变量
当不用的时候应该及时clear
4、将矩阵转化成稀疏形式
如果矩阵中有大量的0,最好存储成稀疏形式。稀疏形式的矩阵使用内存更少,执行时间更短。
5、使用pack命令
当内存被分为很多碎片以后,其实本身可能有很大的空间,只是没有作构的连续空间即大的Block而已。
如果此时Out of Memory,此时使用pack命令可以很好的解决此问题。
6、将一个大矩阵划分成几个小矩阵
使得每次内存的使用量减少
7、增大虚拟内存
Windows XP,右键“我的电脑”->属性->高级->性能->设置,从而改变其虚拟内存。
        Windows 7,右键“计算机”->属性->(左边栏)高级系统设置->高级->(性能)设置->高级->(虚拟内存)更改,
建议物理内存的两倍左右,如果物理内存已经3G+,那就不用调整了。
(1)升级内存
(2)升级64bit系统
(3)增加虚拟内存
(4)采用3G开关启动系统
8、尽量少使用系统资源(对windows)
Windows中字体、窗口等都是要占用系统资源的,所以在Matlab运行时尽量不要打开不用的窗口。
9、如果没有必要不要启动JAVA虚拟机
采用matlab -nojvm启动 (在快捷方式属性里面的 "..../matlab.exe") 改为("...../matlab.exe" - nojvm)


10、关闭MATLAB Server
控制面板-管理工具-服务, 再找到matlabserver对应项,把启动类型的自动改为手动即可
matlab server作为后台服务可以在其它机器上通过网络调用此服务,进行计算任务。
11、Windows中字体、窗口等都是要占用系统资源的,所以在Matlab运行时尽量不要打开不用的窗口。




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


根本上解决内存溢出问题:
1、命令行输入pack整理内存空间
当内存被分为很多碎片以后,其实本身可能有很大的空间,只是没有作构的连续空间即大的Block而已。如果此时Out of Memory,此时使用pack命令可以很好的解决此问题。
2、使用系数矩阵,或者将矩阵转换成稀疏形式 用函数:sparse
如果矩阵中有大量的0,最好存储成稀疏形式。稀疏形式的矩阵使用内存更少,执行时间更短。例如:
1000×1000的矩阵X,它2/3的元素为0,使用两种存储方法的比较:
name  size   bytes       class
 X 1000x1000  8000000  double array
 Y 1000x1000  4004000  double array(sprase)
3、尽量避免产生大的瞬时变量,把没必要的变量clear掉或当它们不用的时候应该及时clear。
4、减少变量,尽量的重复使用变量(跟不用的clear掉一个意思)。
5、把有用的变量先save,后clear 掉,需要时再读出来。


clear save load的特殊用法,对在for或while等多重循环里出现out of memory非常有效。


for k = 1:N %N为循环次数
  var0 = 看; %获得变量var0
  str1 = [sprintf('var_%d', k)' = var0;'];
  eval_r(str1)  %等价于var_k=var0
  save(sprintf('var_%d.mat', k), sprintf('var_%d')); % 等价于 save var_k.mat var_k
  clear(sprintf('var_%d'));   % 等价于 clear var_k
end


如果要读取刚才存取的变量var_k,使用如下方法:
for k = 1:N
  load(sprintf('var_%d.mat', k));     % 等价于 load var_k.mat     k = 1,2, ..., N
end


清除刚才读取的变量 var_k, k = 1, 2, ..., N
clear '-regexp' '^var_'     % 清除所有以“ var_ ”开头的变量


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)

































0 0