Linux下malloc/free详解

来源:互联网 发布:白无常电商美工教学 编辑:程序博客网 时间:2024/05/01 01:02

在程序开发中,堆和栈是最常使用的两个内存区,在Linux下栈分为用户栈和内核栈,内核栈具有固定大小,而用户栈可以通过ulimit来设定,最大8M。

堆具有很大的灵活性,程序员可以根据需要获取任意大小的内存(只只是相对于栈来说,对于32位机,它最大能分配2G多的虚拟地址空间)。malloc/free就是提供给程序员来在堆上分配内存的接口。在堆上分配内存,为什么会产生额外的开销?这些开销是多少? 先来看看堆分配的主要数据结构:

typedef struct free_list {
spin_lock_t lock;/* spin lock for mutual exclusion */
header_t head;/* head of free list for this size */
#ifdef DEBUG
int in_use; /* # mallocs - # frees */
#endif DEBUG
} *free_list_t;

typedef union header {

union header *next;

struct free_list *fl;

} *header_t;

#define MIN_SIZE 8/* minimum block size */

#define NBUCKETS 29

static struct free_list malloc_free_list[NBUCKETS];

通过以上主要的数据结构,我们了解到,malloc额外内存开销主要是,一个malloc_free_list数组(8×29byte),和每malloc一次占用4byte,这样对于小块内存请求来说,效率就比较低。

接下来再分别看看malloc和free的处理流程:

malloc处理流程

1. 首先给size增加sizeof(union header),这是为了把头和待分配的内存块合在一起使用的一个小技巧。

2. 用size去匹配该属于哪个malloc_free_list槽中,malloc_free_list最小8byte,然后每个递增一倍。

3. 匹配上插槽后,然后看这个插槽中有没有空闲的块供分配,如果没有,就调用more_memory来添加,more_memory一次最少需要添加一页。

4.然后就取出freelist中第一个值,free指针下移,返回header+sizeof(union header),这就是供使用的内存。

5.而header中保存的是free list指针,这样当free的时候,就能找到相应的插槽,而不用知道需要释放的内存大小,这也是一个小技巧,屏蔽了额外的开销。


free处理流程

1. free的地址前移sizeof(union header),这样找到freelist指针。

2. 然后把这个单元添加进相应插槽的freelist链表中。


原创粉丝点击