c++内存池的实现

https://github.com/Wchenguang/Memana

代码坐标见上

内存池,申请相对较大的内存免去申请销毁内存的耗时


该实现借鉴了SGI STL的内存管理模型,用链表存储分割成小块的内存块,

MAX_BYTES = 128 当申请内存大于128 用malloc 否则在链表中查找
MINI_BYTES = 8	链表中最小的块
ALIGN = 8 粒度 即链表中内存块大小为8,16,24,32...128
BLOCK_LIST_SIZE = (MAX_BYTES - MINI_BYTES)/ALIGN + 1 block 链表长度


Memana类 维护了一大块内存用于为blockList提供内存块


char *resHead 大内存块的头
char *resTail 大内存块的尾


类中还有关于内存块链的辅助函数

 //内存块链 用于存储 8-128 的零散内存
    Block *blocklist[BLOCK_LIST_SIZE];

    //向上 取小于128的 ALIGN的倍数
    size_t RoundUp(size_t num);

    //向下 取小于12
    size_t RoundDown(size_t num);

    //获取相应 规范size 对应链表的下标
    size_t getIndexInList(size_t size);

    //建立一个内存块 并添加至表中
    void appendBlock(int index, void *data);

    //当 一个内存块链 为空 重新充满
    //默认添加 20 个内存块
    void refillTargetBlocks(size_t index, size_t num = 20);

    //获取 相应大小 与 个数的内存块
    char *getBlocksFromPool(size_t blockSize, size_t &blockNum);

    //获取 相应适合大小的内存块
    Block *getBlock(size_t size);

其公开的接口最重要的两个便是 申请相应大小的内存 与 销毁相应大小的内存(不一定销毁,只是还给链表,若大于128销毁)

//分配内存
    void *allocate(size_t size);

    //回收内存 只回收到链表中 否则不连续
    void dellocate(void *data, size_t size);

采用了单例模式,只有一个实例且无法拷贝。

//单例模式
    static Memana * GetInstance();

Menalloc 采用了简化的型别技术,利用模版及其特化,实现区分了 基本类型,类类型,指针类型,的不同处理方式

若类型匹配则使用特化的模版类,否则使用泛化的模版类

其缘由是

类类型:分配内存后需要运行默认构造函数,释放之前需要运行析构函数 

基本类型,指针类型:无需运行构造函数


其使用实例如下

A *gclass = MemAlloc<A>::Allocate(4);
for(int i = 0; i < 4; ++i){
    std::cout<<gclass[i].b<<std::endl;
}
MemAlloc<A>::Dellocate(gclass, 4);



猜你喜欢

转载自blog.csdn.net/Mr_W1997/article/details/78342615