没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
Uclibc 中的 malloc 机制分析
Uclibc 是嵌入式 linux 系统里面使用最多的 c lib 库。最近在学习 linux 内核内存管理方面的东西,学完
之后一直对用户空间的内存管理很迷糊,特找了 libc 中的 malloc 部份代码研究了一下,小有心得。特总
结成此文。
本文档结构:
一:准备知识
二:堆空间的管理结构
三:堆空间的初始化
四:FA 结构的操作
五:malloc 的实现
六:free 的实现
七:总结
一: 准备知识:
用户空间中,经常会调用 malloc 与 free 进行内存管理,它是在进程的堆空间中分配内存。如下图
所示:
二:堆空间的管理结构:
堆空间表示的数据结构
struct heap
{
//堆空间空闲区的表示结构
struct heap_free_area *free_areas;
//用于在多线程环境中加锁保护
#ifdef HEAP_USE_LOCKING
pthread_mutex_t lock;
#endif
};
作者:ericxiao
MSN:xgr178@163.com
转载请注明出处:
ericxiao.cublog.cn
heap_free_area 结构在代码被代码作者称之为 FA 结构。它的定义如下:
struct heap_free_area
{
//空闲区的大小
size_t size;
//用于构造循环链表
struct heap_free_area *next, *prev;
};
注意:在 FA 结构里并没有定义指向空闲区的指针,这是因为 FA 结构正好放在空闲区的后面。堆栈区
空间结构如下所示:
三:堆空间的初始化:
全局变量__malloc_heap 表示了整个堆栈空间。它的初始化过程如下示:
struct heap __malloc_heap = HEAP_INIT_WITH_FA (initial_fa);
HEAP_INIT_WITH_FA 的定义如下:
#ifdef HEAP_USE_LOCKING
# define HEAP_INIT { 0, PTHREAD_MUTEX_INITIALIZER }
# define HEAP_INIT_WITH_FA(fa) { &fa._fa, PTHREAD_MUTEX_INITIALIZER }
#else
# define HEAP_INIT { 0 }
# define HEAP_INIT_WITH_FA(fa) { &fa._fa }
#endif
变量 initial_fa 初始化如下:
HEAP_DECLARE_STATIC_FREE_AREA (initial_fa, 256);
#define HEAP_DECLARE_STATIC_FREE_AREA(name, size) \
作者:ericxiao
MSN:xgr178@163.com
转载请注明出处:
ericxiao.cublog.cn
static struct \
{ \
char space[(size) - sizeof (struct heap_free_area)]; \
struct heap_free_area _fa; \
} name = { "", { (size), 0, 0 } }
如此可以看出初始化的堆空间为 256 个字节。从上面的初始化也可以看到,在 FA 结构的前面静态定
义了一个数组空间。这也印证了上面说的“FA 结构正好放在空闲区的后面”
四:FA 结构的操作:
1:#define HEAP_FREE_AREA_SIZE(fa) ((fa)->size)
FA 所代表的空闲区大小,此大小已经包含 FA 本身占的空间
2:
#define HEAP_FREE_AREA_START(fa) ((void *)((char *)(fa + 1) - (fa)->size))
FA 所代表空闲区的起始位置。fa+1 到达空闲区末端。指针再下移大小个单位,即为空闲区的起
始位置
3:#define HEAP_FREE_AREA_END(fa) ((void *)(fa + 1))
返回 FA 所表示空闲区的末尾。从 FA 所表示的结构可看出。从 FA 的地址上移一个 FA 的大小,
刚好到达空闲的末尾
4:#define HEAP_MIN_FREE_AREA_SIZE \
HEAP_ADJUST_SIZE (sizeof (struct heap_free_area) + 32)
最少的空闲区大小。空闲区最少要能存上一个 heap_free_area 大小,此外还要有 32 字节的空
闲,这是从效率来考虑的。Malloc 分配内存的时候,有时候它会把一个 FA 分为两段。如果剩余的内
存少于 HEAP_MIN_FREE_AREA_SIZE.还不如全部都将内存分配出去。因为维护空闲内存需要影响效率。
这从我们后面的 malloc 与 free 分析中可以看到
5:
__heap_delete (struct heap *heap, struct heap_free_area *fa)
该函数是将 fa 从 heap 中删除,它的实现如下:
extern inline void
__heap_delete (struct heap *heap, struct heap_free_area *fa)
{
if (fa->next)
fa->next->prev = fa->prev;
if (fa->prev)
fa->prev->next = fa->next;
else
heap->free_areas = fa->next; //如果删除的是它的首节点
}
只是一个简单的链表操作,将 fa 从循环链表中脱节。
6:
__heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
struct heap_free_area *prev,
struct heap_free_area *next)
从代码注释上看该函数是指 prev 与 next 之间的 Fa 合并到一起。实际上它只是在 prev 与 next
之间插入了一项而已。
实现如下:
作者:ericxiao
MSN:xgr178@163.com
转载请注明出处:
ericxiao.cublog.cn
extern inline void
__heap_link_free_area (struct heap *heap, struct heap_free_area *fa,
struct heap_free_area *prev,
struct heap_free_area *next)
{
fa->next = next;
fa->prev = prev;
if (prev)
prev->next = fa;
else
heap->free_areas = fa; //插入节点为首节点的情况
if (next)
next->prev = fa;
}
7:__heap_link_free_area_after (struct heap *heap,
struct heap_free_area *fa,
struct heap_free_area *prev)
该函数实际上只是 fa 链接至 prev 后。等调用的时候再分析它。
__heap_link_free_area_after (struct heap *heap,
struct heap_free_area *fa,
struct heap_free_area *prev)
{
if (prev)
prev->next = fa;
else
heap->free_areas = fa;
fa->prev = prev;
}
8:__heap_add_free_area (struct heap *heap, void *mem, size_t size,
struct heap_free_area *prev,
struct heap_free_area *next)
该函数将从 mem 地址开始的 size 大小的内存所代码的 FA 结构,插入 prev 和 next 之间。它的实现如
下:
extern inline struct heap_free_area *
__heap_add_free_area (struct heap *heap, void *mem, size_t size,
struct heap_free_area *prev,
struct heap_free_area *next)
{
//先取得内存段所在的 FA 结构,再将 FA 结构插入到 prev 与 next 之间
struct heap_free_area *fa = (struct heap_free_area *)
((char *)mem + size - sizeof (struct heap_free_area));
fa->size = size;
作者:ericxiao
MSN:xgr178@163.com
转载请注明出处:
ericxiao.cublog.cn
剩余17页未读,继续阅读
ivanbinson
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页