高并发内存池整体架构
高并发内存池通常分为三个层级,通过分层设计来平衡性能与资源管理。
- 线程缓存(ThreadCache):每个线程独享,用于分配小于 256KB 的内存。由于是线程私有,申请和释放无需加锁,极大提升了并发效率。
- 中心缓存(CentralCache):所有线程共享。当 ThreadCache 空间不足时向其索取对象,同时也负责回收 ThreadCache 中闲置的对象以均衡内存。因存在竞争,获取对象时需加桶锁,但竞争相对温和。
- 页缓存(PageCache):位于 CentralCache 上层,以页为单位存储。当 CentralCache 无可用对象时,从 PageCache 分配页面并切割使用;同时负责合并相邻页缓解内存碎片问题。
⚠️ 核心关注点
在实现过程中,主要需解决以下问题:
- 性能瓶颈:减少系统调用与锁竞争。
- 多线程安全:确保数据一致性。
- 内存碎片:控制内碎片与外碎片的产生。
ThreadCache 设计思路
ThreadCache 采用哈希桶结构,每个桶对应一个按大小映射的自由链表(FreeList)。每个线程维护一个独立的 ThreadCache 实例,这使得线程间获取和释放对象时无需加锁。
虽然这种按对齐数排布的方式缓解了外碎片,但仍需注意内碎片的问题。目前的核心功能聚焦于内存的申请与释放。
- 申请内存:若请求大小 ≤ 256KB,先查找本地 ThreadCache 对应的自由链表。若有空闲对象直接返回;若无,则向 CentralCache 批量获取后放入链表再取出。
- 释放内存:将对象放回 ThreadCache 对应的自由链表。若链表过长,则将多余对象回收到 CentralCache。
FreeList 设计
FreeList 支持插入(Push)和删除(Pop)操作,基于定长内存池的设计思想,利用前指针保存下一个地址。该模块通用性强,后续 CentralCache 也会复用,因此置于公共类中。
class FreeList {
public:
// 头插:将对象加入链表头部
void Push(void* ptr) {
assert(ptr);
*(void**)ptr = _freelist;
_freelist = ptr;
}
// 头删:从链表头部取出对象
void* Pop() {
assert(_freelist);
void* next = *(void**)_freelist;
void* obj = _freelist;
_freelist = next;
return obj;
}
bool {
_freelist == ;
}
:
* _freelist = ;
};


