堆介绍
-
结构示意图
-
-
N位:define NON_MAIN_ARENA 用于表示是否属于主线程,0表示主线程的堆块结构,1表示子线程的堆块结构
-
M位:define IS_MAPPED 0X2 用于表示是否由mmap分配,0表示由堆块中的top chunk分裂产生,1表示由mmap分配
-
P位:define PREV_ISUSE 0x1 用于表示上一堆块是否处于空闲状态,0表示处于空闲状态,1表示处于使用状态。主要用于来判断free是否能够上一堆块进行合并
-
-
堆空闲块管理结构bin
- 当allocated chunk被释放以后,会放入bin或者top chunk中去。bin的作用是加快分配速度,其通过链表方式(chunk结构体中的fd和bk指针)进行管理
- fast bin
- 单链表结构进行组织,用fd指针指向下一堆块,采用LIFO机制
- 它将堆块的p标志为都设为1,处于占用状态,以防止释放时fast bin进行合并,用于快速分配小内存
-
malloc基本规则
- 将申请size按照一定的规则对齐,得到最终要分配的大小size_real
- X86:size+4 按照0x10字节对齐
- X64:size+8按照0x20字节对齐
- 检查size_real 是否符合fast bin 的大小,若是则查看fast bin中对应的size_real 的那条链表中是否存在堆块,若是则分配,否则进行下一步
- 检查size-real 是否符合small bin 的大小,若是则查看fast bin中对应的size_real 的那条链表中是否存在堆块,若是则分配,否则进行下一步
- 检查size-real 是否符合large bin 的大小,若是则调用malloc_consolidate函数对fast bin中所有堆块进行合并,其过程为将fast bin中的堆块取出,清除下一块的p标识位并进行堆块合并,将最终的堆块放入unsorted bin。然后在small bin 和large bin中找到合适size_real大小的块。若找到则分配,并将多余的部分放入unsorted bin ,否则下一步
- 检查top chunk的大小是否符合size_real的大小,若是则分配前面一部分,并重新设置top chunk,否则调用malloc_consolidate函数对fast bin中所有的堆块进行合并,若依然不否,则借助系统调用来开辟新的空间进行分配,若还是不满足,则返回失败
- 将申请size按照一定的规则对齐,得到最终要分配的大小size_real
-
free 基本规则
- 首先会检查地址是否对齐,并根据size找到下一块的位置,检查其p标识位是否为1
- 检查释放块的size是否符合fastbin的大小区间,若是则直接放入fast bin,并保持下一堆块中的p标识位为1不变(这样可以避免在前后块释放时进行堆块的合并,以方便快速分配小内存),否则进行下一步
- 若本堆块size域中的p标识位为0(前一堆块处于释放状态)则利用本快的pre_size找到前一堆块的开头,将其从bin链表中摘除(unlink),并合并这两个块,得到新的释放块
- 根据size找到下一堆块,如果是top chunk,则直接合并到top chunk中,直接返回.否则检查最后一堆块是否处于释放状态(通过检查下一堆块的p标识位是否为0).将其从bin链表中摘除(unlink),并合并这两块,得到新的释放块.
- 将上述合并得到的最终堆块放入unstorted bin中去
-
tcache
- 作用
- 提高堆的使用效率
- 注意点
- tcache的管理是单链表,采用LIFO原则
- tcache的管理结构存在于堆中,默认有64个entry,每个entry最多存放7个chunk
- tcache的next指针指向chunk的数据区
- tcache的某个entry被占满以后,符合该entry大小的chunk被free后的规则和原有机制相同
- 作用