Linux下malloc/free详解

本文发布时间: 2019-Mar-22
在程序开发中,堆和栈是最常使用的两个内存区,在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 DEBUGint 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 29static 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链表中。


(以上内容不代表本站观点。)
---------------------------------
本网站以及域名有仲裁协议。
本網站以及域名有仲裁協議。

2024-Mar-04 02:11pm
栏目列表