基于内存池的空间配置器

一、设计思路

      内存池分两部分,一部分是内存池列表,一部分是没有分割的原始连续内存。

1 内存池列表

      内存池由16个列表组成,每个列表维护大小相同的内存块,内存块的大小是8的倍数。最小的内存块是8字节,最大的内存块是128字节。节点结构图如下:

-------     -------    -------    ------    -----     ------
| 8    |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------
-------     -------    -------    ------    -----     ------
| 16  |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------
-------     -------    -------    ------    -----     ------
| 24  |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------
-------     -------    -------    ------    -----     ------
| 56  |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------
-------     -------    -------    ------    -----     ------
| 64  |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------

…………………………
-------     -------    -------    ------    -----     ------
| 120 |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------
-------     -------    -------    ------    -----     ------
| 128 |--->|     |--->|     |--->|    |--->|    |--->|    |
-------     -------    -------    ------    -----     ------

 

内存池节点结构:

 

union free_list
{
      free_list* next;  


};

 

每个内存块列表的头指针由下面数组维护,其实是一个指针数组,每一个数组元素存放列表的首地址。

static free_list* head_list[POOL_SIZE];

 

2)原生连续内存

       为了提高性能,每次向os申请内存时,会预先分配较大的内存。给内存块列表分配一部分后,剩余的则保存下来。

      //连续内存的起始地址

      static char* start_free;

 

      //连续内存的结尾地址
     static char* end_free;

 

//内存池向os申请内存的总字节数

static size_t heap_size;

 

连续内存块表示:

    -------------------------------------------------------------

   |                                                                            |

   --------------------------------------------------------------

   ^ start_free                                                         ^ end_free

 

3)内存分配策略

叙述之前做一下约定:

req_size ,表示用户请求的内存大小。

 

_round_up(size_t size),表示对用户请求的内存大小,向上调整为8的倍数。

例如:req_size = 14 , 那么_round_up(req_size ) 的返回值是16

 

_pool_watermark(size_t size),表示用户请求的内存在head_list中的下标。

例如:req_size = 14 , 那么_pool_watermark(req_size ) 的返回值是1 

 

具体策略:
1
如果用户申请超过128字节的内存,则直接调用简单空间配置器;否则,执行2)。

2)调用_round_up(req_size ),然后到head_list[_pool_watermark(req_size)中获取内存。

    如果获取成功,返回给用户。否则,执行3)。

3)我们预先会向原生连续内存块申请 20 *_round_up(req_size ) 字节大小的内存,如果原生内存池能满足要求,则返回给客户;否则,如果原生内存剩下的内存大于或者等于req_size,则返回给客户;否则,执行4

4)我们会向os申请 2 * 20 *_round_up(req_size ) + (heap_siz >> 4)大小的内存,如果成功了返回客户。否则调用“简单空间配置器”去申请内存。

4)内存释放策略

如果释放的内存超过128字节,则调用“简单空间配置器”的内存释放函数。否则,释放当相应的内存块列表中。

 

二、源代码

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值