内存池的实现方式

本篇内容介绍了“内存池的实现方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

创新互联是专业的市中网站建设公司,市中接单;提供成都做网站、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行市中网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

这篇文章主要介绍一下内存池的实现方式,这里介绍的是一种比较经典的内存池实现方式,就是链表法实现,具体原理如下:

1,首先内存池无非是提前申请一大块内存片段,之后把这个片段上的指针分配给用户,对于分配来说只要记住已经分配的偏移量即可,每次分配将指针后移申请的内存块长度即可。

2,主要问题在于释放内存,由于不确定用户申请和释放内存的顺序,必须假定申请和释放都在交叠进行,
对于内存池来说,释放的空间必须要可以复用,否则内存池失去了意义;
但是先申请的内存区域可能先释放,这样将出现释放的区域位于已分配区域中间的情形;如何索引这些释放的内存片段是内存池要主要解决的问题;

见下图:

内存池的实现方式

未命名文件.jpg

图中X区域先申请,当申请了Y区域之后,释放了X区域,此时如何能够复用X区域的内存,而不是只能使用Y区域之后的内存时要解决的问题;

内存池的链表法实现见第二幅图,每个申请的区域前有一个固定长度的头部,其中记录了一些信息,最重要的是两个指针,一个指向后面的内存块头部,另一个指向前面的内存块头部,并且末尾的内存块和首部链接起来,构成一个双向环形链表结构;
同时还有个标记位标志这块内存有没被使用;

当申请内存时,从链表首部开始遍历找到第一个没有使用的内存块,判断其大小是否满足,如不满足,继续搜索;直到满足条件,此时分2种情形:
1,可用内存块大小和要申请的大小一样,则直接标记为已使用,并返回即可
2,可用内存块大于要申请的内存块,则把可用内存区间分裂为2部分,前一部分标记为已使用,后一部分标记为未使用,并继续保持它们的链表结构;

对于释放内存,需要判断是否前面和后面相邻的内存块有未使用,如果有,则需要合并,这一步至关重要,因为如果存在大量相邻的标记未使用内存可能会导致无法分配一块较大区域,

以上操作始终保持链表结构,就可以实现一个基础内存池了;
实际上,这个实现思路来自于John Carmack在Quake3中的实现

但是我们可以稍微做一点优化(不过要牺牲一些额外的存储空间)优化方法是,额外记录两个指针,以环形形式连接所有未使用的内存空间,这样,查找的效率提高了,几乎提升到了常数时间,
同时这个内存池还有一个缺陷就是长度固定,不过顺着这个思路,我们可以在内存不够时,新分配一块大的区域,并且保持原来的链表结构即可,

下面附上代码实现,见
https://github.com/wiltchamberian/MemoryPool
这里实现了两个,第一个是参考Quake3 Carmack的实现
第二个SuperMemoryPool是改良后的实现,改良版实现的速度要提高了一些,支持动态内存

“内存池的实现方式”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!


本文名称:内存池的实现方式
标题来源:http://azwzsj.com/article/gcspph.html