LinuxC++项目开发日志——高并发内存池(2-整体框架设计)
文章目录
- 高并发内存池整体框架设计
- 一、引言:多线程内存分配的挑战
- 二、整体架构设计理念
- 一、Thread Cache:无锁分配
- 二、Central Cache:智能调度中心
- 三、Page Cache:内存碎片终结者
高并发内存池整体框架设计
一、引言:多线程内存分配的挑战
现代开发环境普遍采用多核多线程架构,在内存申请场景下,必然存在激烈的锁竞争问题。malloc本身已经是一种优秀的内存分配器,但我们项目的原型tcmalloc在多线程高并发场景下表现更为出色。因此,我们在实现内存池时需要重点考虑以下三方面问题:
-
性能问题
-
多线程环境下的锁竞争问题
-
内存碎片问题
二、整体架构设计理念
三级缓存分层架构:Thread Cache → Central Cache → Page Cache。每层职责分明,协同工作
thread cache:线程缓存是每个线程独有的,用于分配小于256KB的内存。线程从这里申请内存不需要加锁,每个线程独享一个cache,这是并发内存池高效的关键所在。
central cache:中心缓存是所有线程共享的,thread cache按需从central cache中获取对象。central cache会在合适的时机回收thread cache中的对象,避免一个线程占用过多内存而其他线程内存不足,从而实现内存分配在多个线程间的均衡调度。central cache存在竞争,因此从这里获取内存对象需要加锁。这里采用桶锁机制,而且只有在thread cache没有内存对象时才会访问central cache,所以竞争不会很激烈。
page cache:页缓存是位于central cache之上的缓存层,以页为单位存储和分配内存。当central cache没有内存对象时,会从page cache分配一定数量的页,并将其切割成定长大小的小块内存分配给central cache。当一个span的多个页的对象都被回收后,page cache会回收central cache中满足条件的span对象,并且合并相邻的页组成更大的页,从而缓解内存碎片问题。
一、Thread Cache:无锁分配
核心特性
-
线程独享,完全无锁操作
-
处理256KB以下的小内存分配
-
90%以上的分配请求在此完成
关键设计
-
线程本地存储(TLS)实现
-
多规格空闲链表管理
-
自动水位控制与内存回收
二、Central Cache:智能调度中心
核心作用
-
全局内存资源池
-
线程间内存负载均衡
-
连接Thread Cache与Page Cache
创新设计
-
桶锁机制:细粒度锁降低竞争
-
按需分配:仅在需要时介入
-
批量传输:减少锁竞争频率
三、Page Cache:内存碎片终结者
核心使命
-
以页为单位管理系统内存
-
解决外部碎片问题
-
大内存直接分配
关键技术
-
Span结构管理连续内存页
-
相邻空闲页合并算法
-
碎片整理与内存复用