1).考虑到小型区块所可能形成的内存破碎问题,设计了双层级配置器. 设计
当配置区块超过128bytes时,调用第一层级配置器,第一层级配置器直接使用malloc()和free(). 指针
当配置区块小于128bytes时,调用第二层级配置器,采用复杂的memory pool整理方式,下降额外开销. 递归
2).内存池管理方式是每次配置一大块内存,并维护对应之自由链表. 内存
如有相同大小的内存分配,就直接从自由链表中分配内存块. 源码
若内存释放时,则由配置器回收到自由链表中. io
第二级配置器会主动将任何小额区块的内存需求量调至8的倍数. 变量
3).自由链表(free-list)节点的结构以下: 配置
利用union的特性,从第一字段观之,obj可被视为一个指针,指向相同形式的另外一个obj. nio
从第二字段观之,obj可被视为一个指针,指向实际区块. im
一物二用,不会为了维护链表所必须的指针而形成内存的一种浪费.
具体代码实现,请参考STL源码.下面附几张图说明.
第一级配置器与第二级配置器之间的关系:
第二级配置器分配内存时,自由链表变化示意图:
第二级配置器释放内存时,自由链表变化示意图:
第二级配置器分配内存时,其具体步骤以下:
1).判断内存块大小,是否大于128bytes,若大于,则调用第一级配置器.若小于,进行步骤2).
2).从16个自由链表中,根据内存块大小选择合适的自由链表.
3).判断自由链表是否为空,若为空,则从新真充自由链表,不然,进行步骤4).
4).调整当前自由链表指向一块内存块,并返回当前的内存块.(相似于链表的删除操做)
第二级配置器释放内存时,其具体步骤以下:
1).判断内存块大小,是否大于128bytes,若大于,则调用第一级配置器.若小于,进行步骤2).
2).从16个自由链表中,根据内存块大小选择合适的自由链表.
3).调整当前自由链表回收当前的内存块.(相似于链表的插入操做)
内存池的实际操做结果示意图:
内存池管理:
1).三个变量来标识内存池的使用状况和大小,start_free,end_free,heap_size.
2).从内存池中取空间给自由链表时,主要分三种状况进行.
a).内存池剩余空间彻底知足需求量,则直接修改start_free的值,返回对应的区块.
b).内存池剩余空间不能彻底知足需求量,但足够供应一个(含)以上的区块,则减小分配的区块数目,而后分配.
c).内存池剩余空间连一个区块的大小都没法提供,则利用malloc增长内存空间.
若malloc成功,则修改start_free,end_free,heap_size,而后递归调用自身,从新分配区块.
若malloc不成功,则寻找自由链表中,看是否存在足够大的区块.
若存在,则将对应区块做为内存池,调整start_free,end_free,递归调用自身,从新分配区块.
若不存,则调用第一级配置器.