高并发内存池C++

三层结构:              

                                                  

 

PageCache:

内存的单位是页,一页的大小是4KB,从操作系统中最多申请128页,维护128个链表,每个链表的每个节点存放对应数量的页。

节点结构体:

//记录页的内容
typedef size_t  PageID;
struct Span{

void *_objlist = nullptr;//分配的地址的头指针   因为分配内存返回的是void*头指针。
Span *_prev = nullptr; //指向前一个对象
Span *_next = nullptr;//指向后一个对象

size_t _pages = 0; //记录有几页
PageID _pageid = 0; //记录开始页号
size_t _objsize = 0; //记录centralCache中每一块的大小
size_t _usecount = 0;//记录被使用了多少块
};

 

class PageCache{

private :

std::mutex _mtx; //多进程需要上锁
SpanList _spanlist[MAXPAGES + 1]; //链表数组,管理不同页数的Span对象
static PageCache _Inst; //创建单例模式所需
Radix<Span *> _page_id_span; //页号与Span对象对应的映射
 

public:

PageCache() = default; //默认构造函数
PageCache(const PageCache&) = delete; //禁止拷贝
PageCache operator = (const PageCache&) = delete; //禁止赋值

static PageCache *GetInstance(){
    return &_Inst;
}

Span *_NewSpan(size_t npage); //从操作系统获取内存,或者从数组链表中获取Span对象返回给NewSpan函数。

Span *NewSpan(size_t npage); //CentralCache从PageCache获取Span对象

void RealeaseSpanToPageCache(Span *span); //合并Span对象

Span *GetIdToSpan(size_t id); //根据页号获取Span对象
};

 

CentralCache:

从PageCache中获取Span对象,将Span对象连续的页给拆分成固定字节的块,这些块在Span对象里形成链表,给ThreadCache分配块。CentralCache维护Span对象。

内存的基本单位是块,128字节范围内8字节对齐,1024 字节范围内16字节对齐,8*1024字节范围内128字节对齐,64*1024字节范围内1024字节对齐。总共有240种。

CentralCache只是对对象链表上锁,多线程的时候就比全部上锁快。

class CentralCache{

private:

static CentralCache _inst;
SpanList _spanlists[MAXBLOCKS + 1]; //存放Span对象的链表

public:

CentralCache() = default; //默认构造函数
CentralCache(CentralCache &) = delete; //禁止拷贝
CentralCache operator = (CentralCache &) = delete; //禁止赋值

static CentralCache* GetCentralInstance(){ //单例模式
    return &_inst;
}

Span *GetOneSpan(size_t size); //从PageCache中或者CentralCache数组链表中获取Span对象,并且分块。

size_t FetchRangeObj(void *&start,void *&endd,size_t num,size_t size); //ThreadCache向CentralCache中请求num个size字节大小的块,分配来自GetOneSpan对象。

void ReleaseListToSpans(void *start,size_t size); //合并块

};

ThreadCache:

内存单位也是块,和CentralCache中分块范围是一样的。使用某种机制,一下子申请多个内存块。从CentralCache获取void*内存指针,数组链表将维护void*指针。

class ThreadCache{

private:
FreeList _freelist[MAXBLOCKS + 1];

public:

void *Allocate(size_t sizes); //用户向ThreadCache申请内存。

void *FetchFromCentralCache(size_t index,size_t sizes); //ThreadCache向CentralCache申请内存。

void Deallocte(void *ptr,size_t sizes); //用户释放内存放入FreeList中管理,达到一定条件调用ListTooLong释放内存。
void ListTooLong(FreeList &freelists,size_t num,size_t sizes); //释放内存。

};

源文件:等找到一个地方放原码之后上传。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值