两级allocator:
当请求内存较大(大于128bytes)时,采用第一级allocator
小于128bytes时,采用第二级allocator,采用内存池的方法管理小内存.
内存申请大于128bytes时,第一级allocator直接调用malloc和free函数,并模拟C++的set_new_handler函数处理内存不足的情况。
第二级allocator则复杂很多,具体实现包括:
维护16个自由链表(free_list),负责16种不同大小的内存空间分配。0:8;1:16…;15:120 bytes
自由链表的内存由内存池分配,而内存池则由malloc函数分配内存
如果内存不足或请求内存大于128bytes则转调第一级allocator
第二级allocator用内存池管理已分配但未使用的内存,当客户端请求内存时,首先查询free-list中是否有适当大小的内存块,如果有直接分配该内存块并将该内存块从freelist中移除。如果freelist没有匹配大小的可用内存块,则调用chunk_alloc()函数向内存池申请内存。chunk_alloc函数根据情况,处理申请请求:
1.默认分配20个用户索取区块大小的内存块,将其中一个返回给客户,剩余19个加入合适的free-list中
2.如果内存池中内存不足以分配20个区块(根据end_free和start_free可以查看内存池“水位”),那么就分配内存池剩余内存可以分配的最大区块数,比如剩余100bytes,请求内存块大小为32bytes,则分配3个区块
3.如果内存池中剩余内存连一个区块都不能分配了,那么就向heap申请内存,但是需要把残余的内存分配到相应的freelist中,比如客户申请32bytes内存,但是内存池只剩下20bytes,那么就将这20bytes加入free-list管理16bytes的list中,这样只会产生4bytes的内存碎片
roundup上调到8的倍数