MATLAB学习之内存溢出的管理方法
今天用Matlab跑程序,由于数据量太大,又出现 Out of memory. Type HELP MEMORY for your options.的问题。看到这篇文章非常实用,转过来方便查阅~
用 Matlab 进行大规模科学计算或仿真时,内存是一个需要时常注意的问题。在matlab里运行
>>system_dependent memstats
就可以看到内存的使用状况。当你写的 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 XP Professional" /noexecute=optin /fastdetect /3G
5. 如果必有必要,不要启动java虚拟机,采用matlab -nojvm启动 (在快捷方式属性里面的 "..../matlab.exe") 改为("...../matlab.exe" - nojvm)
6. 关闭Matlab Server
控制面板-管理工具-服务, 再找到matlabserver对应项,把启动类型的自动改为手动即可
matlab server作为后台服务可以在其它机器上通过网络调用此服务,进行计算任务。
7. Windows中字体、窗口等都是要占用系统资源的,所以在Matlab运行时尽量不要打开不用的窗口。
除此以外,更关键的是需要弄清楚以下几个问题:
问题一:Matlab是如何存储矩阵的?
Matlab中矩阵是以Block,也就是块的形式存储的。也就是说,当Matlab在为即将存储的矩阵划分块时,如果没有相应大小的连续内存,即使实际内存没有被完全使用,它还是会报告“Out of Memory”。
问题二:如何高效使用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,最好存储成稀疏形式。稀疏形式的矩阵使用内存更少,执行时间更短。例如:
000×1000的矩阵X,它2/3的元素为0,使用两种存储方法的比较:
Name
Size
Bytes
Class
X
1000x1000
8000000
double array
Y
1000x1000
4004000
double array (sparse)
3. 尽量避免产生大的瞬时变量,把没必要的变量clear掉或当它们不用的时候应该及时clear。
4. 减少变量,尽量的重复使用变量(跟不用的clear掉一个意思)。
5. 把有用的变量先save,后clear 掉,需要时再读出来。
下面介绍一下关于clear、save、load的特殊用法,这对在for或while等多重循环里出现out of memory非常有效。
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')); % 等价于 save var_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)); % 等价于 load var_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 of Memory。而当你为矩阵变量预制内存时,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管理内存。当在Matlab heap中没有足够的内存使用时,它会向系统请求内存。但是只要内存碎片可以存下当前的变量,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 possible array: 15 MB (1.622e+007 bytes) *
Memory available for all arrays: 194 MB (2.036e+008 bytes) **
Memory used by MATLAB: 1549 MB (1.624e+009 bytes)
Physical Memory (RAM): 4095 MB (4.294e+009 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
这是清理之后:
Maximum possible array: 252 MB (2.641e+008 bytes) *
Memory available for all arrays: 988 MB (1.036e+009 bytes) **
Memory used by MATLAB: 762 MB (7.991e+008 bytes)
Physical Memory (RAM): 4095 MB (4.294e+009 bytes)
* Limited by contiguous virtual address space available.
** Limited by virtual address space available.
文章转自:http://hi.baidu.com/flyingsnow0102/blog/item/98266c1955b512f5ae51331b.html
MATLAB学习之内存溢出的管理方法的更多相关文章
- Java常见的几种内存溢出及解决方法
Java常见的几种内存溢出及解决方法[情况一]:java.lang.OutOfMemoryError:Javaheapspace:这种是java堆内存不够,一个原因是真不够(如递归的层数太多等),另一 ...
- MyEclipse 2015 运行tomcat 内存溢出的解决方法
内存溢出错误: 2016-3-16 11:19:55 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() ...
- 【移动开发】EditText输入字数限制总结(包括中文输入内存溢出的解决方法)
限定EditText输入个数的解决方案很多,但是一般主要考虑两点,也就是处理两件事:(1)不同语言字符(英文.中文等)处理方式(2)输入字符达到数目后,是否仍然允许用户输入 第一点,涉及的东东其实蛮多 ...
- jvm 内存溢出问题排查方法
如果你做TCP通讯或者map集合操作,并发处理等功能时,很容易出现 Java 内存溢出的问题.本篇文章,带领大家深入jvm,分析并找出jvm内存溢出的代码. jvm中除了程序计数器,其他的区域都有可能 ...
- Android EditText输入字数限制总结(包含中文输入内存溢出的解决方法)
转载请注明,大飞:http://blog.csdn.net/rflyee/article/details/38856539 限定EditText输入个数的解决方式非常多,可是一般主要考虑两点.也就是处 ...
- Jenkins内存溢出的处理方法
参考:http://openwares.net/java/jenkens_deploy_to_tomcat_error_of_outofmemoryerror.html上的说明,有如下解释: -Xms ...
- JVM内存溢出环境备份方法
线上Tomcat服务内存溢出,且不容易重现,又没配置JMX监控端口,如何在不重启Tomcat的情况下备份堆dump和线程dump,进而分析原因? 因为Tomcat以服务模式运行,直接用JVisualV ...
- Ecshop 后台导出订单Excel时, 内存溢出的解决方法
今天继续跟大家分享一下,在我配置Ecshop时的问题. 今天的问题是在后台想要导出订单列表Excel时出现的内存溢出.错误提示如下 问题: Fatal error: Allowed memory s ...
- php查询mysql返回大量数据结果集导致内存溢出的解决方法
web开发中如果遇到php查询mysql返回大量数据导致内存溢出.或者内存不够用的情况那就需要看下MySQL C API的关联,那么究竟是什么导致php查询mysql返回大量数据时内存不够用情况? 答 ...
随机推荐
- java正则表达式去除html中所有的标签和特殊HTML字符(以&开头的)
来源于:https://www.androiddev.net/java%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%8E%BB%E9%99%A4ht ...
- 设置cnblogs默认滚动条样式
默认滚动条样式丑嘛就不谈了~这里修改为个性化滚动条样式. CSS代码 /*滚动条整体样式*/ body::-webkit-scrollbar { width: 10px; height: 1px; } ...
- 客户端调用rcf库 时,返回值千万不要用auto
std::vector<std::wstring> list = Client.xxxx(); 千万不要写成 auto list = Client.xxxx();
- ubuntu下安装配置minicom(解决默认的端口/dev/tty8,改不过来的问题)
Minicom是linux下串口通信的软件,下面讲下ubuntu Minicom的安装和配置. 安装: sudo apt-get install minicom 或在新立得软件包管理器中搜索“mini ...
- <welcome-file>index.action</welcome-file>直接设置action,404和struts2中的解决方案
这几天的项目页面的访问全部改为.action访问,在修改首页时遇到了问题.将web.xml文件中<welcome-file>index.action</welcome-file> ...
- 学习asp.net的流程
如果你已经有较多的面向对象开发经验,跳过以下这两步: 第一步 掌握一门.NET面向对象语言,C#或VB.NET 我强烈反对在没系统学过一门面向对象(OO)语言的前提下去学ASP.NET. ASP.NE ...
- source insight 相对路径新建工程
在创建source insight工程时,最好用“相对路径”,并“将si的工程文件,保存到源码包里”! 这样一来,等以后,将源码包放置于硬盘上其他位置,或分发给其他人,或改了源码包的名称,si工程仍然 ...
- NTC与PTC压敏电阻在电源电路中起的作用
https://wenku.baidu.com/view/e39beafdfab069dc502201f9.html 压敏电阻的作用 http://www.eepw.com.cn/article/27 ...
- U811.1接口EAI系列之五--材料出库--VB语言
主要业务有:09其他出库单 11:材料出库单 32:销售出库单 主要业务代码: '材料出库生成XML Public Function xml_storeout(ds_head As MSHFlexGr ...
- Java 打印程序设计实例
3.1 打印文本 3.1.1 应用场景 假设我们需要打印一个窗体的某个文本编辑域(可能只有几行,也可能包含多页)的内容,并且每页最多打印 54 行,如何实现呢? 3.1.2 解决方法 基本思路如下:首 ...