在UCGUI窗口创建过程都涉及到了内存的分配,那如何分配的呢,先看下面的一张图:
从上图可以看出主要由内存池,内存块和一个记录器
1.内存池主要是由在.bss段,而bss段,和未初始化或者初始化为0的.Data段数据不占据空间,但占据标识。其形式如下
typedef union
{
int aintHeap[GUI_ALLOC_SIZE/4]; /* required for proper alignement */
U8 abHeap[GUI_ALLOC_SIZE];
} GUI_HEAP;
2.内存块:主要是记录分配给窗口句柄的BLOCK在内存池中位移地址,占据大小等,其形式如下:
typedef struct
{
tALLOCINT Off; /* Offset of memory area */
tALLOCINT Size; /* usable size of allocated block */
HANDLE Next; /* next handle in linked list */
HANDLE Prev;
} tBlock;
3.内存记录器,主要记录着内存使用多少,剩余多少,用了多少内存块,未用的内存块
了解了大概后,现在分析下UCGUI怎样实现这些的
1.从目标机器拿出一块内存,做为内存池,记住要为全局变量且未初始化,因为这关系着程序的大小,定义全局变量GUI_HEAP GUI_Heap; (其结构在本文的上端可找出)
2.在内存池中画出内存块BLOCK个数,其个数根据内存大小来划分,其中有可能剩余,也可能超出
3.初始化内存记录器,记录现在的内存池里面的情况。并且从内存池中拿出第一块BLOCK用于记录内存对齐,并占据大小为对齐大小的不同而不同。
4.初始化完毕后,就可以用ALLOC函数开始分配了!
ALLOC函数的实现步骤如下:
1. 检查是否初始化了内存池所需数据,若未则初始化。
2. 判断所要分配的大小,根据内存对齐的多少决定要分配内存的大小
3. 检查是否大于内存池剩余内存大小,如果超出则不分配
4. 查找出未使用的内存块,若找不到,也无法分配内存
5. 查找之前分配的内存块中,是否有一块其内存字节数和前一个内存字节中间有HOLE,而且这个HOLE刚好大于所需的SIZE,则把它分配成一块新的BLOCK
6. 分配到后面如果内存块的大小不足以分配,则查找是否HOLE,把所有的HOLE集中起来,看是否所有HOLE的大小足以分配
7. 记录内存情况,以及当前BLOCK块的记录!
8. 最后把当前BLOCK初始化为0
struct
{
int NumUsedBlocks, NumFreeBlocks, NumFreeBlocksMin; /* For statistical purposes only */
tALLOCINT NumUsedBytes, NumFreeBytes, NumFreeBytesMin;
} GUI_ALLOC;