您的位置:首页 > 其它

【内存管理】STL空间配置器

2012-06-05 19:29 218 查看
下面主要介绍STL中实现的内存空间配置器.

关键点:

1).考虑到小型区块所可能造成的内存破碎问题,设计了双层级配置器.

当配置区块超过128bytes时,调用第一层级配置器,第一层级配置器直接使用malloc()和free().

当配置区块小于128bytes时,调用第二层级配置器,采用复杂的memory pool整理方式,降低额外开销.

2).内存池管理方式是每次配置一大块内存,并维护对应之自由链表.

若有相同大小的内存分配,就直接从自由链表中分配内存块.

若内存释放时,则由配置器回收到自由链表中.

第二级配置器会主动将任何小额区块的内存需求量调至8的倍数.

3).自由链表(free-list)节点的结构如下:



利用union的特性,从第一字段观之,obj可被视为一个指针,指向相同形式的另一个obj.

从第二字段观之,obj可被视为一个指针,指向实际区块.

一物二用,不会为了维护链表所必须的指针而造成内存的一种浪费.

具体代码实现,请参考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,递归调用自身,重新分配区块.

若不存,则调用第一级配置器.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: