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);