文章目录
- 堆和堆管理器
- arena
- chunk
- malloc chunk
- free chunk
- bin
- fastbins
- unsorted bin
- small bins
- large bins
- fastbins结构
- bin的双向链表结构
堆和堆管理器
堆是内存中一块连续的空间,由堆管理器管理。
堆管理器不是由操作系统实现,是在libc中实现的。其中封装了一些系统调用来管理申请来的内存,同时为用户提供接口。
主要使用两个系统调用:brk(break),mmap(memory map)
主线程可以用brk和mmap,子线程只能用mmap。
其次如果主线程申请的空间较大的话,也需要用mmap。
arena
arena(内存分配区)
可以理解为堆管理器所持有的内存池
堆管理器与用户的内存交易发生在arena中
当线程比较少的时候,每个线程可以拥有自己的arena,
而当 arena 数目超过允许最大值时,多个线程共享一个arena。
chunk
chunk是用户申请内存的基本单位,也是堆管理器管理内存的基本单位
malloc函数返回的指针就指向一个chunk的数据区域
chunk的数据结构
struct malloc_chunk {
INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
struct malloc_chunk* bk_nextsize;
malloc chunk
32位系统通过malloc申请内存的chunk如下图
p=0时,表示前一个chunk为空闲,prev_size才有效。
p=1时,表示前一个chunk正在使用,prev_size无效 p主要用于内存块的合并操作。
free chunk
bin
管理arena中空闲chunk的结构
以数组的形式存在,数组元素为相应大小的chunk链表的链表头,
存在于arena的malloc_state中
主要分为unsorted bin
、fast bins
、small bins
、large bins
fastbins
存储于fastbinsY[]
单向列表,后进先出
32位下默认管理16\24\32\40\48\56\64字节的free chunk
其中的chunk的p位(相邻下一个chunk的p位)一定是1
因为fastbin单独记录,需要让其他bins认为是被用的,不会被合并
unsorted bin
bins[1]
管理刚刚释放的还未被分类的chunk
small bins
bins[2]~bins[63]
32个循环双向链表
先进先出
32位下默认管理16\24\32\40…\504字节的free chunk
每个链表中存储的chunk大小都一致
large bins
bins[64]~bins[126]
63个循环双向链表
先进先出
32位下管理大于504字节的free chunk
注意只有fastbins是单向链表
fastbins结构
bin的双向链表结构