请教一个内存问题管理中的问题

安全检查中...
请打开浏览器的javascript,然后刷新浏览器
< 浏览器安全检查中...
还剩 5 秒&查看: 404|回复: 3|关注: 0
请教批量读取excel过程中内存管理的问题以及解决办法
<h1 style="color:# 麦片财富积分
新手, 积分 20, 距离下一级还需 30 积分
本帖最后由 qiuhuizuo 于
15:12 编辑
操作系统xp 32位,cpu i5&&,内存4G,matlab版本R2010b,excel 2007 。目前使用matlab批量读取2000+ excel文件。文件全部放在同一个文件夹下。读取到1927时程序中断并产生报错信息。附件中是任务管理器的截图。下方是程序代码以及报错代码。请高手看看是什么问题,如何解决?十分感谢!
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function [b c xlsstr xlsdata] =inputexcel(k)
%根据给出的地址,将文件夹中的excel文件全部录入到指定的mat文件中
path=k;%根据给出的地址将默认目录跳转到对应的地址
%
%
prxlsstr={};%定义存放利润表excel文字的cell
prxlsdata={};%定义存放利润表excel数据的cell
prxlsall={}; %定义存放利润表excel全部内容的cell
blxlsstr={};%定义存放资产负债表excel文字的cell
blxlsdata={};%定义存放资产负债表excel数据的cell
blxlsall={}; %定义存放资产负债表excel全部内容的cell
bijiao=strfind(path,'Profit') %如果地址中包含profit,则数据保存在profitsamp.mat中
if bijiao&1
a=dir(path);& && &&&%读入目录下文件信息存储为结构体形式
prb=struct2cell(a); %将格式转为cell形式
prb(:,1:2) = [];& & %将b结构体第一列和第二列所有行都设为空。因为这些是根目录内容
prc=prb(1,:);& && &&&%取出其中文件名单元
[h,l]=size(prc);& &%计算文件个数
jj=0;& && && && & %循环计数数值初始化
for ii=1:l
file_address=strcat(path,prc{ii});
if strfind(prc{ii},'.xls')& & %如果是xls文件格式 根据c的数据结构从第一个数据开始检查该文件是否是xls格式,如果不是就跳出本次循环进入下一循环
jj=jj+1;& && && && && && &&&%如果该是xls文件格式,计数器加1 。
[prxlsdata{jj},prxlsstr{jj},prxlsall{jj}]=xlsread(file_address); %同时读取c1所对应的excel文件,将文本数据和数字数据分别存放
jj
system('taskkill /F /IM EXCEL.EXE')
end
end
& &save profitsamp prb prc prxlsstr prxlsdata prxlsall
end
bijiao=strfind(path,'Banlanc')&&%如果地址中包含Banlanc,则数据保存在Banlancsamp.mat中
if bijiao&1
& & a=dir(path);& && &&&%读入目录下文件信息存储为结构体形式
& & blb=struct2cell(a); %将格式转为cell形式
& & blb(:,1:2) = [];& & %将b结构体第一列和第二列所有行都设为空。因为这些是根目录内容
& & blc=blb(1,:);& && &&&%取出其中文件名单元
& & [h,l]=size(blc);& &%计算文件个数
& & jj=0;& && && && & %循环计数数值初始化
for ii=1:l
file_address=strcat(path,blc{ii});
if strfind(blc{ii},'.xls')& & %如果是xls文件格式 根据c的数据结构从第一个数据开始检查该文件是否是xls格式,如果不是就跳出本次循环进入下一循环
jj=jj+1;& && && && && && &&&%如果该是xls文件格式,计数器加1 。
[blxlsdata{jj},blxlsstr{jj},blxlsall{jj}]=xlsread(file_address); %同时读取c1所对应的excel文件,将文本数据和数字数据分别存放
jj
system('taskkill /F /IM EXCEL.EXE')
end
end
& &save Banlancsamp blb blc blxlsstr blxlsdata blxlsall
end复制代码
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
??? Out of memory. Type HELP MEMORY for your options.
Error in ==& xlsread&parse_data
Error in ==& xlsread at 318
& & [data,text] = parse_data(rawData);
Error in ==& inputexcel at 48
[blxlsdata{jj},blxlsstr{jj},blxlsall{jj}]=xlsread(file_address); %同时读取c1所对应的excel文件,将文本数据和数字数据分别存放
Unexpected error status flag encountered.&&Resetting to proper state.
&& help memory
MEMORY Memory information.
& & See 'doc memory' for more information on how to make the
& & best use of memory when running MATLAB.
& & MEMORY when called without an output argument displays
& & information about how much memory is available and how
& & much is currently being used by MATLAB. All values are double
& & precision and in units of bytes.
& & USERVIEW = MEMORY returns information about how much memory is
& & available and how much is currently being used by MATLAB. USERVIEW
& & is a structure that contains the following fields:
& && & MaxPossibleArrayBytes -- The largest contiguous free memory block.
& && && & It is an upper bound on the largest single array that MATLAB can
& && && & currently create. This field is the smaller of these two values:
& && && && & a) The largest contiguous memory block found in the
& && && && && & MATLAB virtual address space, or
& && && && & b) The total available system memory.
& && && & To find the number of elements, divide MaxPossibleArrayBytes
& && && & by the size of each element in bytes. For example, divide by
& && && & eight for a double matrix. The actual number of elements that
& && && & that can be created is always less than this number.
& && & MemAvailableAllArrays -- The total amount of memory available
& && && & for data. This field is the smaller of these two values:
& && && && & a) The total available MATLAB virtual address space, or
& && && && & b) The total available system memory.
& && && & The amount of memory available is guaranteed to be at least
& && && & as large as this field.
& && & MemUsedMATLAB -- The total amount of system memory reserved for the
& && && & MATLAB process. This is the sum of the physical memory and
& && && & potential swap file usage.
& & [USERVIEW, SYSTEMVIEW] = MEMORY returns additional, and more detailed
& & information about the current state of memory usage.&&SYSTEMVIEW is a
& & structure containing the following:
& && & VirtualAddressSpace -- A 2-field structure that contains the
& && && & amount of available memory and the total amount of virtual
& && && & memory for the MATLAB process.
& && & SystemMemory -- A 1-field structure that contains the amount of
& && && & available system memory. This number includes the amount of
& && && & available physical memory and the amount of available swap file
& && && & space on the computer running MATLAB.
& && & PhysicalMemory -- A 2-field structure that contains the amount of
& && && & available physical memory and the total amount of physical memory
& && && & on the computer running MATLAB.&&It can be useful as a measure
& && && & of how much data can be accessed quickly.
& & The MEMORY function is currently available on PCWIN and PCWIN64 only.
& & Results will vary depending on the computer running MATLAB, the load
& & on the computer, and what MATLAB is doing at the time.
& & Example 1: Run the MEMORY command on a 32-bit Windows system:
& && &&&&& memory
& && &&&Maximum possible array:& && && && & 677 MB (7.101e+008 bytes) *
& && &&&Memory available for all arrays:& &1602 MB (1.680e+009 bytes) **
& && &&&Memory used by MATLAB:& && && && &&&327 MB (3.425e+008 bytes)
& && &&&Physical Memory (RAM):& && && && & 3327 MB (3.489e+009 bytes)
& && &&&*&&Limited by contiguous virtual address space available.
& && &&&** Limited by virtual address space available.
& && &&&&&
& & Example 2: Run the MEMORY command on a 64-bit Windows system:
& && &&&&& memory
& && &&&Maximum possible array:& && && && && &4577 MB (4.800e+009 bytes) *
& && &&&Memory available for all arrays:& && &4577 MB (4.800e+009 bytes) *
& && &&&Memory used by MATLAB:& && && && && &&&330 MB (3.458e+008 bytes)
& && &&&Physical Memory (RAM):& && && && && & 3503 MB (3.674e+009 bytes)
& && &&&*&&Limited by System Memory (physical + swap file) available.
& && &&&&&
& & Example 3: Run the MEMORY command with two outputs on a 32-bit Windows
& && && && && &system:
& && &&&&& [uV sV] = memory
& && &&&uV =
& && && && &MaxPossibleArrayBytes:
& && && && &MemAvailableAllArrays: 1.
& && && && && && &&&MemUsedMATLAB:
& && &&&sV =
& && && && &VirtualAddressSpace: [1x1 struct]
& && && && && && & SystemMemory: [1x1 struct]
& && && && && &&&PhysicalMemory: [1x1 struct]
& && &&&&& sV.VirtualAddressSpace
& && &&&ans =
& && && && &Available: 1.
& && && && && & Total: 2.
& && &&&&& sV.SystemMemory
& && &&&ans =
& && && && &Available: 4.
& && &&&&& sV.PhysicalMemory
& && &&&ans =
& && && && &Available: 2.
& && && && && & Total: 3.
& & Reference page in Help browser
& && & doc memory
论坛优秀回答者
<h1 style="color:#6 麦片财富积分
关注者: 34
为什么要全部录入一个mat?这对内存要求很高,matlab也不是无限制可以使用内存的
说说你的目的,可以改算法节约内存使用
<h1 style="color:# 麦片财富积分
这些excel文件总共不超过50M。我录入.mat的目的就是遍历数据,进行数据检索。
<h1 style="color:# 麦片财富积分
请问解决了么?该怎么办呢?
站长推荐 /2
快速搭建新能源汽车整车模型及其性能优化
MATLAB中文论坛是全球最大的 MATLAB & Simulink 中文社区。用户免费注册会员后,即可下载代码,讨论问题,请教资深用户及结识书籍作者。立即注册加入我们吧!
MATLAB官方社交平台
MATLAB中文论坛微社区PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 &#8211; 左手代码 右手诗
PHP的内存管理,
分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理.
而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等.
另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法.
而在我们平时开发扩展, 修复PHP的bug的时候, 却对这一部分的知识需要有一个良好的理解. PHP开发组内的很多朋友也对这块不是很清楚, 所以我觉得有必要专门写一下.
一些基本的概念, 我就不赘述了, 因为看代码很容易能看懂,
我这里就主要介绍几个看代码没那么容易看懂的点,
为什么这么说呢,
呵呵, 我在写文章之前, 查找了下已有的资料, 已避免重复功,
其中看到了TIPI项目对这部分的描述,
发现其中错误很多.
所以, 我想这部分就是看代码也没那么容易看懂的点
目前, 英文版的介绍也在撰写中:
Zend Memory Manager, 以下简称Zend MM, 是PHP中内存管理的逻辑.
其中有一个关键数据结构: zend_mm_heap:
Zend MM把内存非为小块内存和大块内存俩种, 区别对待, 对于小块内存, 这部分是最最常用的, 所以追求高性能. 而对于大块内存, 则追求的是稳妥, 尽量避免内存浪费.
所以, 对于小块内存, PHP还引入了cache机制:
Zend MM 希望通过cache尽量做到, 一次定位就能查找分配.
而一个不容易看懂的点是free_buckets的申明:
Q: 为什么free_buckets数组的长度是ZEND_MM_NUMBER_BUCKET个?
A: 这是因为, PHP在这处使用了一个技巧, 用一个定长的数组来存储ZEND_MM_NUMBER_BUCKET个zend_mm_free_block, 如上图中红色框所示.
对于一个没有被使用的free_buckets的元素, 唯一有用的数据结构就是next_free_block和prev_free_block, 所以, 为了节省内存, PHP并没有分配ZEND_MM_NUMBER_BUCKET * sizeof(zend_mm_free_block)大小的内存, 而只是用了ZEND_MM_NUMBER_BUCKET * (sizeof(*next_free_block) + sizeof(*prev_free_block))大小的内存..
我们来看ZEND_MM_SMALL_FREE_BUCKET宏的定义:
#define ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
(zend_mm_free_block*) ((char*)&heap-&free_buckets[index * 2] + \
sizeof(zend_mm_free_block*) * 2 - \
sizeof(zend_mm_small_free_block))
之后, Zend MM 保证只会使用prev和next俩个指针, 所以不会造成内存读错..
那么, 第二个不容易看懂的点, 就是PHP对large_free_buckets的管理, 先介绍分配(TIPI项目组对此部分的描述有些含糊不清):
static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size)
large_free_buckets可以说是一个建树和双向列表的结合:
large_free_buckets使用一个宏来决定某个大小的内存, 落在什么index上:
#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)
zend_mm_high_bit获取true_size中最高位1的序号(zend_mm_high_bit), 对应的汇编指令是bsr(此处, TIPI项目错误的说明为: &#8220;这个hash函数用来计算size的位数,返回值为size二进码中1的个数-1&#8243;).
也就是说, 每一个在large_free_buckets中的元素, 都保持着指向一个大小为在对应index处为1的size的内存块的指针.
诶, 有点绕口, 举个例子:
比如对于large_free_buckets[2], 就只会保存, 大小在0b1大小的内存. 再比如: large_free_buckets[6], 就保存着大小为0bb大小的内存的指针.
这样, 再分配内存的时候, Zend MM就可以快速定位到最可能适合的区域来查找. 提高性能.
而, 每一个元素又同时是一个双向列表, 保持着同样size的内存块, 而左右孩子(child[0]和child[1])分别代表着键值0和1, 这个键值是指什么呢?
我们来举个例子, 比如我向PHP申请一个true_size为0b11010大小的内存, 经过一番步骤以后, 没有找到合适的内存, PHP进入了zend_mm_search_large_block的逻辑来在large_free_buckets中寻找合适的内存:
1. 首先, 计算true_size对应的index,
计算方法如之前描述的ZEND_MM_LARGE_BUCKET_INDEX
2. 然后在一个位图结构中, 判断是否存在一个大于true_size的可用内存已经存在于large_free_buckets, 如果不存在就返回:
size_t bitmap = heap-&large_free_bitmap &&
if (bitmap == 0) {
return NULL;
3. 判断, free_buckets[index]是否存在可用的内存:
if (UNEXPECTED((bitmap & 1) != 0))
4. 如果存在, 则从free_buckets[index]开始, 寻找最合适的内存, 步骤如下:
从free_buckets[index]开始,
如果free_buckets[index]当前的内存大小和true_size相等, 则寻找结束, 成功返回.
查看true_size对应index后(true_size <child[1]下面继续寻找, 如果free_buckets[index]->child[1]不存在, 则跳出.
如果true_size的当前最高位为0, 则在free_buckets[index]->child[0]下面继续寻找, 如果free_buckets[index]->child[0]不存在, 则在free_buckets[index]->child[1]下面寻找最小内存(因为此时可以保证, 在free_buckets[index]->child[1]下面的内存都是大于true_size的)
4.3. 出发点变更为2中所述的child, 左移一位ture_size.
5. 如果上述逻辑并没有找到合适的内存, 则寻找最小的&#8221;大块内存&#8221;:
/* Search for smallest &large& free block */
best_fit = p = heap-&large_free_buckets[index + zend_mm_low_bit(bitmap)];
while ((p = p-&child[p-&child[0] != NULL])) {
if (ZEND_MM_FREE_BLOCK_SIZE(p) & ZEND_MM_FREE_BLOCK_SIZE(best_fit)) {
best_fit =
注意上面的逻辑,
(p = p->child[p->child[0] != NULL]), PHP在尽量寻找最小的内存.
为什么说, large_free_buckets是个键树呢,
从上面的逻辑我们可以看出, PHP把一个size, 按照二进制的0,1做键, 把内存大小信息反应到了键树上, 方便了快速查找.
另外, 还有一个rest_buckets,
这个结构是个双向列表,
用来保存一些PHP分配后剩下的内存, 避免无意义的把剩余内存插入free_buckets带来的性能问题(此处, TIPI项目错误的描述为: &#8220;这是一个只有两个元素的数组。 而我们常用的插入和查找操作是针对第一个元素,即heap->rest_buckets[0]&#8220;).
Related Posts:
Filed in ,
Leave a Reply
开发组核心成员, 顾问, PHP7主要开发者, , , 等开源项目作者.

我要回帖

更多关于 内存条和主板兼容问题 的文章

 

随机推荐