一种高效快速的内存池实现(附源码)

此算法灵感来自于apache内存池实现原理,不过读者如果没有看过apache内存池实现也无关系,因为本算法相对apache内存池算法更为简单而且易懂,个人认为某些场合也更为高效,或许真正到了apache服务器上性能不如,但是这套设计思想应该还是可以借鉴到更多场合的。

我们在调用malloc函数时,操作系统内部会查找一个所谓的空闲链表,当找到足够大的空闲空间时会将内存分割并返回一部分会用户,当然在很大的项目里面有可能会出现链表所有节点都找不到空闲空间的情形,此时操作系统便会不断搜索内存碎片,然后组合成一段足够大的空间并返回,如果此时还找不到便返回NULL。所以在new或者malloc调用后程序员有必要对申请的内存做是否为NULL的判断。而且在调用free后系统有可能还要合并内存产生额外开销,另外不断的malloc和free也会产生很多内存碎片并给操作系统管理内存带来很大的压力。所以说内存池算法在很多场合是非常必须的。

这套内存池算法分为两套数组,其中一套数组固定长度,另一套数组为变长数组,至于变长算法模仿于STL的vector。在长度不够时扩容复制原数组内容到新数组中,并且销毁原数组。

固定长度的数组是图上FastMemPool箭头所指方向,分为A8,B16到E40。图中只画 出来这么多,实际可以更为扩充到(8,16,24,32,...,112,120,128),这方便理解思想。数组中每个元素索引称为外部索引。该数组中每个元素存储一个边长数组起始地址,比如A  8,就存储内存大小为8字节的内存数组列,也就是说A1到A8每个具体的数组单元都是8字节。

当程序需要申请内存的时候,首先根据需要申请内存大小来对其,计算出来对其后是多少,例如如果要申请5字节的内存,对其后就是8,那么需要从A1到A8当中寻找一块没有使用的内存返回给程序。具体对其规则可参见源码。

变长数组则是MemPoolAlloc也就是向下箭头所指A1到A8这部分,变长规则是首先申请10个元素空间,当满了以后申请更大空间的内存,然后将原始数组复制过来,填入新数据,这部分和STL vector算法原理技术相当但不完全一致,读者了解即可。数组中每个元素索引称为内部索引。

申请内存时,首先每一列边长数组都是空的。外部程序第一次调用内存池接口时,首先会从系统malloc申请,但是申请时会增加一个结构体大小空间,具体结构体定义如下

struct MemPoolData
{
    unsigned int    dwMemTrunkTicket;
    unsigned char   chbIsMemTrunkUsed;
    unsigned char   chOutIndex;
    unsigned char   chInIndex;
};

该结构体包含的这块内存在内存池中的外部索引与内部索引,包含这些信息,我们可以一步找到这块内存在整个内存中的什么位置。同时包含着这块内存上一次被释放是什么时间,如果太长时间不用可以销毁掉节约内存。也包含着一个内存是否被使用信息。

申请内存后内存池会填写好这些信息,然后返回给用户。当用户释放内存时会根据这些信息一步找到这块内存在内存池中的位置并标记已被回收而且填好时间。

以上A1到A8为例,假设整个内存池序列有n个,也就是A1到An,绝对会存在m(1<=m<=n),保证A1到Am为空闲状态,Am到An为被使用状态。

也就是说,如果内存池A1到An全部没有被使用,当申请内存时,只需要检查A1是否为空闲状态即可。有的可以返回,如果不是空闲,说明整个A序列内存都已经被占用了。当A1空闲,那么申请内存后将A1状态标记为被使用状态,然后将A1和An调换,此时保证内存池前n-1为未使用状态,n为使用状态。

同样的道理,再次申请则将调整后的A1和A(n-1)调换,保证A1到A(n-2)为空闲状态,最后两个元素为被使用状态。

释放内存时,假设内存池序列是A1到Am为空闲,A(m+1)到An为被使用,而被使用的内存肯定是随机在m+1到n的某个元素,那么将其标记为未使用状态之后马上与m+1这个元素调换,此时保证A1到A(m+1)空闲,后A(m+2)到An为未使用。

所以说内存池中不管怎么申请释放或者调整,始终保证A1到Am空闲,之后的为被使用状态。如果中间有元素太长时间没被使用而释放,此时也需要根据这规则做调整。因为这样申请内存时不需要查表就可以找到元素,而释放内存时也能根据内存池管理数据结构中的外部和内部索引一步找到内存池中的位置,这也是该内存池高效的原因之一。

那么按照以上规则,假如说A1到A8都已经满员而且全都没有被使用,再次申请8字节内存时,首先检查A1这块内存是否已经被使用,如果被使用就无法申请。但是如果没有被使用则返回给程序,标记此内存已经被使用。然后将A8内存和A1调换,记录一个索引7,代表A1到A7没有被使用,A7以后的数据被使用了。同样的道理再次申请时仍然直接检查A1,因为没被使用则返回给程序,再将A1与A7调换,此时A1到A6没有被使用,A6到A8被使用了。

释放内存时,假如说A1到A3未被使用而A4到A8被使用,释放的内存是A6,则将A6标记为未使用状态,将A4与A6调换即可。

另外如果申请和释放内存时,系统函数会锁住整个内存管理队列,而这套算法只会锁住当前大小序列,也就是说,申请8字节大小和申请16字节大小内存时不会产生锁竞争。因为8字节大小操作只是锁住A序列,16大小则是锁住图上的B序列。每个序列都有自己独立的锁。这也是高效快速的原因之一。

源码:MemPoolTest.zip

时间: 2024-08-04 22:18:43

一种高效快速的内存池实现(附源码)的相关文章

【网站国际化必备】Asp.Net MVC 集成Paypal(贝宝)快速结账 支付接口 ,附源码demo

开篇先给大家讲段历史故事,博主是湖北襄阳人.襄阳物华天宝,人杰地灵,曾用名襄樊.在2800多年的历史文化中出现了一代名相诸葛亮(卧龙),三国名士庞统(凤雏),魏晋隐士司马徽(水镜先生),唐代大诗人孟浩然(孟襄阳),张继.杜审言,文学家皮日休,北宋著名书画家米芾(米襄阳),“允冠百王”的光武帝刘秀,东方圣人释道安等一大批历史文化名人.小说<三国演义>120回故事中有30多回提到襄阳. 相传诸葛亮的老婆黄月英黄头发黑皮肤,但知识广博.诸葛亮发明木牛流马,就是从黄月英的传授的技巧上发展出来.不仅如此

30种奇妙的鼠标悬停效果【附源码下载】

Web 界面上交互的方式很多,只要你去探索,你会发现很多让你眼前一亮的想法.Codrops 最近发布了一组悬停效果,总共分为两组,多达30种不同的风格.为了让效果尽可能的平滑,最好不要在元素上使用变换以免影响布局.第二组效果中采用了 SVG 动画,这也是目前比较流行的方式. 温馨提示:为保证最佳的效果,请在 IE10+.Chrome.Firefox 和 Safari 等现代浏览器中浏览. 在线演示      源码下载 您可能感兴趣的相关文章 网站开发中很有用的 jQuery 效果[附源码] 分享

酷毙了!三种风格的全屏幻灯片效果【附源码下载】

今天,我们想向您展示如何创建平铺背景图像的幻灯片效果.其灵感来自于国外的一个工作室网站(围观),这个网站充满了各种有趣和创意效果,一定记得去看看. 这个幻灯片效果是由四个区域的独立移动构成,通过画面分割,同时显示出新的图片.这里需要组合使用 CSS3 的3D转换.过渡和动画功能.除了这种效果我们也将添加两个更多的变化,我们的宗旨是实现超流畅的交互体验. 温馨提示:为保证最佳的效果,请在 IE10+.Chrome.Firefox 和 Safari 等现代浏览器中浏览. 源码下载      在线演示

Log4Qt快速入门——Log4Qt日志输出重定向源码解析

Log4Qt快速入门--Log4Qt日志输出重定向源码解析 一.Appender简介 1.Appender简介 Appender是所有Appender的抽象类,是对记录日志形式的抽象.Log4Qt(Qt4版本)中Appender继承体系如下: 2.Appender接口 virtual Filter *filter() const = 0; virtual QString name() const = 0; virtual Layout *layout() const = 0; virtual b

c++实现游戏开发中常用的对象池(含源码)

c++实现游戏开发中常用的对象池(含源码) little_stupid_child2017-01-06上传 对象池的五要素: 1.对象集合 2.未使用对象索引集合 3.已使用对象索引集合 4.当前使用量 5.最大使用量 http://download.csdn.net/download/little_stupid_child/9730912

spring学习笔记2---MVC处理器映射(handlerMapping)三种方式(附源码)

一.根据Beanname访问controller: 在springmmvc-servlet.xml的配置handlermapping中加入beanname,通过该beanname找到对应的controller实现控制 1 <!-- 配置HandlerMapping 根据beanname找到对应Controller --> 2 <bean 3 class="org.springframework.web.servlet.mvc.support.ControllerBeanName

3种精美Web前端搜索框展示(附源码)

1.  jQuery按栏目搜索框代码 赶紧来体验一下. 源码下载/  在线演示 2.  CSS3带凹槽搜索框 这个插件集成了一些非常好的 JavaScript 库,提供一个方便使用的文本动画插件. 源码下载/  在线演示 3.jQuery视频侧边隐藏搜索框 jquery实现的,会在当鼠标光标移动到接近(或通过)视口(viewport)的顶部的时候触发. 源码下载 /   在线演示 3种精美Web前端搜索框展示(附源码)

3种精美Web前端搜索框展示(附源码)(二)

4.  CSS3响应式伸缩搜索框 能在支持 FireFox.Chrome.Safari.傲游.搜狗.360浏览器. 源码下载 /   在线演示 5.  css3带搜索框下拉菜单 源码下载 /   在线演示 6.  jQuery当乐网搜索下拉框 源码下载 /   在线演示 3种精美Web前端搜索框展示(附源码)(二)

时尚设计!三种奇特的网格加载效果【附源码下载】

如果你看过三星企业设计中心网站,你肯定已经注意到了时尚的网格加载效果.每一项加载的时候,背景色会首先滑出,然后图像显现出来.滑动颜色表示图像,也就是说它是彩色图像的主色. 在这篇文章中,我们想向您展示了如何使用 Masonry 网格砌体插件,结合 CSS 动画重现这种效果.另外在这里,我们还借助了 ColorFinder 来获得的图像的最突出的颜色来作为初始的加载背景色使用. 立即下载      在线演示 温馨提示:为保证最佳的效果,请在 IE10+.Chrome.Firefox 和 Safar