uCGUI动态内存管理
动态内存的堆区
/* 堆区共用体定义 */
typedef union { /* 可以以4字节来访问堆区,也可以以1个字节来访问 */
int aintHeap[GUI_ALLOC_SIZE / ]; /* required for proper alignement */
U8 abHeap[GUI_ALLOC_SIZE];
} GUI_HEAP; /* 堆区的数据 */
GUI_MEM_ALLOC GUI_HEAP GUI_Heap GUI_ALLOC_LOCATION;
管理动态内存需要的管理信息节点结构体
/* 动态内存管理信息节点结构体 */
/* 通过管理节点结构体就可以定位一个数据块在堆区中的位置和大小,以及其前一个和后一个数据块的节点信息 */
/* 由此,可以遍历整个堆区,这也就是uCGUI动态内存管理的一种方法,主要体现在这种数据结构上 */
typedef struct {
GUI_ALLOC_DATATYPE Off; /* Offset of memory area */ //一个数据块在动态内存中的相对地址偏移
GUI_ALLOC_DATATYPE Size; /* usable size of allocated block */ //数据块的大小
HANDLE Next; /* next handle in linked list */ //前一个数据块的管理信息节点在aBlock中的位置
HANDLE Prev; //后一个数据块的管理信息节点在aBlock中的位置
} tBlock; /* 管理信息节点的结构体链表 */
static tBlock aBlock[GUI_MAXBLOCKS]; 其中GUI_MAXBLOCKS的定义如下:
#ifndef GUI_MAXBLOCKS
#define GUI_MAXBLOCKS (2 + GUI_ALLOC_SIZE / 32)
#endif
记录堆区整体使用情况的结构体
/* 记录堆区使用情况的结构体 */
struct {
int NumUsedBlocks, //已经使用的数据块数目
NumFreeBlocks, //还未使用的数据块数目
//(注意这里指的是管理信息节点存储区aBlock的使用情况)
NumFreeBlocksMin; /* For statistical purposes only */
GUI_ALLOC_DATATYPE NumUsedBytes, //堆区已经使用的字节数
NumFreeBytes, //堆区还未使用的字节数
NumFreeBytesMin;
} GUI_ALLOC;
漫谈uCGUI管理动态内存区的方法
动态内存分配和释放是动态内存库函数提供给用户最基本的功能,额外的功能包括查询当前堆区的使用情况、可利用情况、可使用的单块的最大size等。动态内存的库函数实现有不同的方法,可以不需要借助于堆区以外的管理结构体,仅仅使用堆区以内少量的空间作为堆区的管理空间,笔者曾经实现过,参考如何实现一个malloc函数。动态内存的管理如果借助于堆区以外的管理结构体,自然消耗了更多的RAM空间,但是管理的效果自然提升很多。这里主要体现在分配和释放的速度,堆区的内存碎片整理,以及堆区使用情况的监控。
uCGUI就是通过借助于堆区以外的管理结构体来实现动态内存的管理。其中堆区就是有效的数据区,堆区的管理不会占用这里边的空间。节点信息管理结构体数组aBlock,它的元素个数是根据堆区大小和预定义一个分配数据块大小确定的。uCGUI还定义了一个记录堆区使用情况的全局信息结构体变量GUI_ALLOC。
当用户欲从堆区中分配一定大小的数据块,首先根据全局信息结构体变量GUI_ALLOC记录的可使用情况,核查当前堆区是否能够满足用户的需求,显然如果没有足够的空间,直接就以错误的形式返回。接下来,要从aBlock数组中获取一个信息管理结构体节点,获取到的节点在数组中的位置,也就是它是数组的第几个元素,被定义为句柄。然后根据节点信息管理结构体数组记录的块信息,从堆区中找到一个可以使用的块。最后,将这个分配到的块信息记录在之前分配到的管理节点中,就完成了它们之间的绑定。还需要对应的修改全局信息结构体变量GUI_ALLOC相应元素的值。
常用的malloc函数动态获取一个内存块后返回的是这个内存块的首地址,而uCGUI返回的是这个内存块在节点管理数组中的位置,也就是句柄。当前uCGUI完全可以做到返回内存块的地址,但是uCGUI分配到的内存块是用来保存窗口和控件的管理信息的,使用句柄比使用内存块的首地址更具有优势。
Attention:
uCGUI的节点信息管理结构体数组一个元素分配之后,对应着一个数据块。一个窗口在创建的时候,通常只占用一个32个字节的数据块(这里假定NumExtraBytes为0)。但是,一个控件创建的时候,占用了不止一个数据块,耗费的空间也非常大。
uCGUI动态内存管理的更多相关文章
- C++动态内存管理之shared_ptr、unique_ptr
C++中的动态内存管理是通过new和delete两个操作符来完成的.new操作符,为对象分配内存并调用对象所属类的构造函数,返回一个指向该对象的指针.delete调用时,销毁对象,并释放对象所在的内存 ...
- Keil C动态内存管理机制分析及改进(转)
源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...
- (原创)动态内存管理练习 C++ std::vector<int> 模拟实现
今天看了primer C++的 “动态内存管理类”章节,里面的例子是模拟实现std::vector<std::string>的功能. 照抄之后发现编译不通过,有个库函数调用错误,就参考着自 ...
- FreeRTOS 动态内存管理
以下转载自安富莱电子: http://forum.armfly.com/forum.php 本章节为大家讲解 FreeRTOS 动态内存管理,动态内存管理是 FreeRTOS 非常重要的一项功能,前面 ...
- C++程序设计入门 引用和动态内存管理学习
引用: 引用就是另一个变量的别名,通过引用所做的读写操作实际上是作用于原变量上. 由于引用是绑定在一个对象上的,所以定义引用的时候必须初始化. 函数参数:引用传递 1.引用可做函数参数,但调用时只需 ...
- 动态内存管理详解:malloc/free/new/delete/brk/mmap
c++ 内存获取和释放 new/delete,new[]/delete[] c 内存获取和释放 malloc/free, calloc/realloc 上述8个函数/操作符是c/c++语言里常用来做动 ...
- oracle结构-内存结构与动态内存管理
内存结构与动态内存管理 内存是影响数据库性能的重要因素. oracle8i使用静态内存管理,即,SGA内是预先在参数中配置好的,数据库启动时就按这些配置来进行内在分配,oracle10g引入了动态内存 ...
- 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体
1.字符串输出输入函数 读入字符串的方法: 1) scanf 特点:不能接收空格 2) gets 特点:可以接受含有空格的字符串 ,不安全 3) fgets(); 特点:可以帮我们自动根据数组的长度截 ...
- 动态内存管理---new&delete
动态内存管理 动态对象(堆对象)是程序在执行过程中在动态内存中用new运算符创建的对象. 因为是用户自己用new运算符创建的.因此也要求用户自己用delete运算符释放,即用户必须自己管理动态内存. ...
随机推荐
- 分享一个字数限制和统计的UITextView分类方法
- (NSUInteger)letterCountWithLimits:(NSInteger)limits { NSString *toBeString = self.text; NSUInteger ...
- java编程常用技术
一:将String字符串放在最前面 防止发生NullPointerException异常,我们通常把String字符串放在equals方法的左边来比较,这样可以有效的避免 空指针异常的发生. 第一种情 ...
- 一致性Hash算法及使用场景
一.问题产生背景 在使用分布式对数据进行存储时,经常会碰到需要新增节点来满足业务快速增长的需求.然而在新增节点时,如果处理不善会导致所有的数据重新分片,这对于某些系统来说可能是灾难性的. 那 ...
- session的介绍与简单使用
cookie由浏览器带着,容易被篡改因为cookie很容易被篡改,所以cookie用来记住用户名,记住浏览历史等安全性要求不高的地方可以用sessin技术session技术将信息存入服务器,然后再给客 ...
- 【高性能服务器】Tomcat剖析
引言 Tomcat是一个流行的servlet容器,对于开发人员来说整体和容器打交道有必要花一些时间爱你了解其内部结构.本文将从一下几个方面来剖析其内部结构. 整体结构 连接器 初始化过程 如何处理一个 ...
- DropdownListFor无法正确绑定值-同名问题
DropdownListFor无法正确绑定值 如果以下面的方式进行绑定: <%: Html.DropDownListFor(model => model.subType, ViewBag ...
- Javascript的作用域、作用域链以及闭包
一.javascript中的作用域 ①全局变量-函数体外部进行声明 ②局部变量-函数体内部进行声明 1)函数级作用域 javascript语言中局部变量不同于C#.Java等高级语言,在这些高级语言内 ...
- SSH无密码登陆问题解决
转载 http://my.oschina.net/hunzi/blog/10687 安装好Cygwin后,SSH需要设置为无密码登陆, 首先查看是ssh还是ssh2:ls -l `which ssh` ...
- mysqld-nt: Out of memory (Needed 1677720 bytes)解决方法
http://www.jb51.net/article/58726.htm 今天发现网站有点慢,发现mysql日志中提示mysqld-nt: Out of memory (Needed 1677720 ...
- SVN-钩子
先说说钩子是干什么的吧,,简单的说,svn钩子就是在提交svn时前后所要触发的事件,于是我们可以用钩子做一些提交时的限制,及提交后的操作.最常用的一般有两个,pre-commit,post-commi ...