本文主要是介绍[项目][CMP][Central Cache]详细讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- 1.设计&结构
- 2.申请内存
- 3.释放内存
- 4.框架
1.设计&结构
- Central Cache也是一个哈希桶结构,它的哈希桶的映射关系跟Thread Cache是一样的
- 不同的是它的每个哈希桶位置挂的是SpanList链表结构(带头双向循环链表),不过每个映射桶下面的span中的大内存块被按映射关系切成了一个个小内存块对象挂在span的自由链表中
- 8Byte映射位置下面挂的是span中的页被切成8Byte大小的对象的自由链表
- 256KB位置的span中的页被切成256KB大小对象的自由链表
2.申请内存
- 当Thread Cache中没有内存时,就会批量的向Central Cache申请一些内存对象
- 这里的批量获取对象的数量使用了类似网络tcp协议拥塞控制的慢开始算法
- Central Cache也有一个哈希映射的spanlist,spanlist中挂着span,从span中取出对象给Thread Cache,这个过程是需要加锁的,不过这里使用的是一个桶锁,尽可能提高效率
- Central Cache映射的spanlist中所有span的都没有内存以后,则需要向Page Cache申请一个新的span对象,拿到span以后将span管理的内存按大小切好作为自由链表链接到一起,然后从span中取对象给Thread Cache
- Central Cache中挂的span中use_count记录分配了多少个对象出去,分配一个对象给Thread Cache,就++use_count
3.释放内存
- 当Thread Cache过长或者线程销毁,则会将内存释放回Central Cache中
- 释放回来时-- use_count,当use_count减到0时则表示所有对象都回到了span,则将span释放回Page Cache, Page Cache中会对前后相邻的空闲页进行合并
4.框架
// 单例
class CentralCache
{
public:static CentralCache *GetInstance(){return &_sInit;}// 从Central Cache获取一定数量的对象给Thread Cache// start, end 输出型参数,带回地址size_t FetchRangeObj(void *&start, void *&end, size_t batchNum, size_t alignSize);// 获取一个非空的spanSpan *GetOneSpan(SpanList &list, size_t size);// 将一定数量的对象释放到span跨度void ReleaseListToSpans(void *start, size_t alignSize);
private:CentralCache(){}CentralCache(const CentralCache &) = delete;
private:SpanList _spanLists[NFREELIST];static CentralCache _sInit;
};
这篇关于[项目][CMP][Central Cache]详细讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!