基于内存池的空间配置器

news/2024/7/4 0:52:09 标签: list, up, os, class
class="baidu_pl">
class="article_content clearfix">
class="htmledit_views">

一、设计思路

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

1 内存池列表

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

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

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

 

内存池节点结构:

 

union free_class="tags" href="/tags/LIST.html" title=list>list
{
      free_class="tags" href="/tags/LIST.html" title=list>list* next;  


};

 

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

static free_class="tags" href="/tags/LIST.html" title=list>list* head_class="tags" href="/tags/LIST.html" title=list>list[POOL_SIZE];

 

2)原生连续内存

       为了提高性能,每次向class="tags" href="/tags/OS.html" title=os>os申请内存时,会预先分配较大的内存。给内存块列表分配一部分后,剩余的则保存下来。

      //连续内存的起始地址

      static char* start_free;

 

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

 

//内存池向class="tags" href="/tags/OS.html" title=os>os申请内存的总字节数

static size_t heap_size;

 

连续内存块表示:

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

   |                                                                            |

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

   ^ start_free                                                         ^ end_free

 

3)内存分配策略

叙述之前做一下约定:

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

 

_round_class="tags" href="/tags/UP.html" title=up>up(size_t size),表示对用户请求的内存大小,向上调整为8的倍数。

例如:req_size = 14 , 那么_round_class="tags" href="/tags/UP.html" title=up>up(req_size ) 的返回值是16

 

_pool_watermark(size_t size),表示用户请求的内存在head_class="tags" href="/tags/LIST.html" title=list>list中的下标。

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

 

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

2)调用_round_class="tags" href="/tags/UP.html" title=up>up(req_size ),然后到head_class="tags" href="/tags/LIST.html" title=list>list[_pool_watermark(req_size)中获取内存。

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

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

4)我们会向class="tags" href="/tags/OS.html" title=os>os申请 2 * 20 *_round_class="tags" href="/tags/UP.html" title=up>up(req_size ) + (heap_siz >> 4)大小的内存,如果成功了返回客户。否则调用“简单空间配置器”去申请内存。

4)内存释放策略

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

 

二、源代码

 

class="MsoNormal" style="margin: 0cm 0cm 0pt;"> 


http://www.niftyadmin.cn/n/1870233.html

相关文章

STL空间配置器的适配器

前面讲了simple_alloc 和alloc_pool将会作为bbg的STL容器的空间配置器,但是这两个类都不是泛型的,不能为所有类型自动提供内存分配,这时候就需要一个空间配置器的适配器来完成这功能。 我们将会通过下面一组预编译的宏,来决定到底…

STL空间构造器

当c程序用new/delete运算符进行动态内存操作时,编译器为我们准备了两项工作。一是,调用全局内存分配函数 operator new() / operator delete(); 二是,调用 “构造函数”和“析构函数”。 下面举个例子说明: class Te…

使用JDBC连接数据库(一)

JDBC是由java编程语言编写的类及接口组成,同时它为程序开发人员提供了一组用于实现对数据库访问的JDBC API,并支持SQL语言。利用JDBC可以将JAVA代码连接到oracle、DB2、SQLServer、MYSQL等数据库,从而实现对数据库中的数据操作的目的。 一、JDBC简介 J…

小议c++文件流中文件路径

1.1 小议c文件流中文件路径 在论坛中闲逛时,经常发现有朋友调试c/c文件流的代码时,遇到文件路径的问题。下来我结合自己的经验,一起探讨一下。 1.1.1 文件路径的基本概念 OS的文件系统是一个树状结构,有目录、文件的概念。…

字面常量(literal constant)

在我们的程序中经常会出现,整数、浮点数、字符、字符串,在c 中还有 true 、false等。例如: bool gz (int b ){return b > 0 ? true : false;}int main(int argc, char *argv[]) { 22 33L;char *str "hello world";3.0 2…

在具有多态特性的类体系中,向客户提供使用接口,而不去暴露类的体系结构。

先举个例子,我们在开发中,经常会处理很多异步消息,比如:io消息、信号、定时器等,现在我们就建立一个消息处理器系统,代码如下: struct msg{ int msg_id;char data[1];};class BaseMsgProcess…

求出32位整数左边第一位是1的算法

算法思路&#xff1a; 总体采用分治法 1、先将32位分成两个16位 2、在16位中再分析出8为&#xff0c;依次类推 unsigned ffs(unsigned n){ if (n 0) return 0; unsigned c 32; if (!(n & 0xffff0000)) { c - 16; n << 16; } …

c++中的左移、右移运算

移位运算包含“逻辑移位”&#xff08;logical shift&#xff09;和“算术移位”&#xff08;arithmetic shift&#xff09;。 逻辑移位&#xff1a;移出去的位丢弃&#xff0c;空缺位&#xff08;vacant bit&#xff09;用 0 填充。 算术移位&#xff1a;移出去的位丢弃&…