1. 项目概述:高并发内存池中的CentralCache角色
在构建高并发内存池的架构中,CentralCache作为承上启下的关键层级,承担着内存资源调度中枢的职责。这个模块位于ThreadCache(线程局部缓存)和PageCache(页缓存)之间,主要负责平衡多个线程之间的内存分配需求。与ThreadCache的线程私有特性不同,CentralCache是整个进程内所有线程共享的全局资源,需要处理来自不同线程的并发请求。
CentralCache的核心设计目标是在保证线程安全的前提下,实现高效的内存块分配与回收。当某个ThreadCache的内存不足时,会向CentralCache批量申请内存块;而当ThreadCache内存过剩时,又会将多余的内存块返还给CentralCache。这种设计既避免了线程间的激烈竞争,又保证了内存资源的合理流动。
2. CentralCache的核心数据结构解析
2.1 SpanList哈希桶结构
CentralCache采用哈希桶的方式组织内存块,每个桶对应特定大小的内存块需求。例如在常见的实现中,可能会设置从8字节到256KB不等的多个桶,每个桶管理特定尺寸的内存块。这种设计使得内存分配可以在O(1)时间复杂度内完成。
每个哈希桶内部维护的是一个Span的双向链表,每个Span代表一段连续的内存页。Span结构中通常包含以下关键字段:
_pageId:起始页号_n:页数量_objList:内存块链表_useCount:被使用计数
cpp复制struct Span {
PageID _pageId; // 起始页号
size_t _n; // 页数量
void* _objList; // 内存块链表
size_t _useCount;// 被使用计数
Span* _next; // 双向链表指针
Span* _prev;
};
2.2 线程安全控制机制
由于CentralCache会被多个线程并发访问,必须实现高效的线程安全控制。常见的方案包括:
- 桶级锁:为每个哈希桶配备独立的互斥锁,这样不同桶的操作可以并行进行
- CAS原子操作:对于简单的计数器更新,使用原子操作避免锁开销
- 细粒度锁:在Span层面增加锁控制,减少锁竞争范围
提示:在实际实现中,应该避免使用全局锁,否则会严重限制系统的并发性能。桶级锁是一个较好的折中方案。
3. CentralCache的核心操作实现
3.1 内存分配流程详解
当ThreadCache向CentralCache申请内存时,会触发以下处理流程:
- 根据请求的内存大小确定对应的哈希桶
- 获取该桶的锁(防止并发修改)
