对一个内存池的分析

最近分析学习了一个内存池程序源代码。关于这个内存池的作者和源代码,可以从这个链接中得到(http://256.com/sources/mpool/)。下面打算对我这些日子的理解做个总结,把学到的记下来。

 

我只能给出一个概述,对一些太过于细节的就不做记录了。这里说到的内存池特指上面链接中的内存池。

 

关于性能

    原本一直以为C语言自带的malloc或者calloc的速度很慢,经过测试之后才发现是在不断重复大量的malloc/free后,malloc才会变得很慢,可能就是传说中的有大量内存碎片影响了速度吧。如果只是少量的malloc/freemalloc还是很快的,内存池就显得特别慢了。内存池适用于这样的程序:大量重复mallocfree,所申请内存的大小变化不大。这里说的重复mallocfree是说内存的使用上存在类似于mallocfreemallocfreemallocfree ……这样的序列。

     其实所谓的内存池就是一种内存管理策略。如用什么数据结构组织内存,每次申请多少内存,如何释放内存等等。标准库的malloc等函数已经实现了很不错的内存策略,貌似标准库使用了红黑树或散列表的方式来管理进程堆。不同的内存策略有不同的优劣。不同程序可能需要不同的内存策略。为了减少内存碎片,提高内存利用率,有些时候需要比较特殊的内存策略,那就需要自己编写内存池了。下面要介绍的内存池使用了散列表。

 

数据结构

    内存池维护着两个表:一个是已申请的内存块列表,另一个是空闲内存块索引表。如下图。

    内存池

    上图中的内存块分成内存块头部和可用部分。内存块头部存放着内存块大小,下一个内存块地址等信息。可用部分在空闲时,会被赋值一个空闲头部,以存放空闲块大小和下一个空闲块地址等信息。如下图。

      内存块

    内存块列表存放所有内存块(包括在用的和空闲的),当最后要删除内存池的时候,只需要释放这个列表就可以了。每次新申请的内存块都会被插入到列表头。当释放内存会池中时,不需要将内存块从该列表中移走。

    空闲块列表是一个对空闲内存块的索引列表,编号N存放可用内存大小大于2N且小于2(N+1)的内存块。每当有内存块被释放回池中时,会根据这个内存块的大小被放在对应的索引列表中,插入时和内存块列表相同,放在列表头。

 

学而时习之

    分析完Gray Watson的内存池源码后,我根据自己的理解和回忆,模仿mpool写了一个自己的内存池,虽然大部分和Gray的是一样的,但还是对一些局部的算法做了简化或者修改。比如对空闲队列做排序,以提高空闲块的利用率(牺牲了速度),简化了各个结构体结构等等。有兴趣可以通过http://download.csdn.net/source/2885263下载

 

后记

     这几天继续学习内存管理,才发现之前对内存管理的了解还十分幼稚。这里推荐一篇不错的文章——《内存管理内幕》。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值