高并发内存池

解决的问题

池化技术 申请过量资源 自己管理以便后续使用

内碎片 外碎片

内碎片:由于对齐的需要,已分配的内存块中未使用的部分

外碎片:内存中不连续的难以使用的块

c语言中的malloc其实就是一个内存池,malloc相当于向操作系统申请了一块很大的内存空间,然后按需求分配给程序使用。

高并发内存池整体框架设计

concurrent memory pool主要以三个部分构成

1.thread cache 线程缓存每个线程独有 用于小于256kb的内存分配 线程从这里申请内存不需要加锁,每个线程独享一个cache,这也就是这个并发线程池高效的地方

2.central cache:中心缓存是所有线程所共享,thread cache是按需从central cache中获取的对
象。central cache合适的时机回收thread cache中的对象,避免一个线程占用了太多的内存,而
其他线程的内存吃紧,达到内存分配在多个线程中更均衡的按需调度的目的。central cache是存
在竞争的,所以从这里取内存对象是需要加锁,首先这里用的是桶锁,其次只有thread cache的
没有内存对象时才会找central cache,所以这里竞争不会很激烈。


3. page cache:页缓存是在central cache缓存上面的一层缓存,存储的内存是以页为单位存储及分配的,central cache没有内存对象时,从page cache分配出一定数量的page,并切割成定长小
的小块内存,分配给central cache。当一个span的几个跨度页的对象都回收以后,page cache
会回收central cache满足条件的span对象,并且合并相邻的页,组成更大的页,缓解内存碎片
的问题。

thread cache

thread cache是哈希桶结构,每个桶是一个按桶位置映射大小的内存块对象的自由链表,每个线程都会有一个thread cache对象,通过自己的tls获取,这样每个线程在这里获取对象和释放对象是无锁的。

内存申请: 
1. 当内存申请size<=256KB,先获取到线程本地存储的thread cache对象,计算size映射的哈希桶自由链表下标i。
2. 如果自由链表_freeLists[i]中有对象,则直接Pop一个内存对象返回。
3. 如果_freeLists[i]中没有对象时,则批量从central cache中获取一定数量的对象,插入到自由链表并返回一个对象。

释放内存: 
1. 当释放内存小于256k时将内存释放回thread cache,计算size映射自由链表桶位置i,将对象Push到_freeLists[i]。
2. 当链表的长度过长,则回收一部分内存对象到central cache。

这个方法帮我们取到下一个对象

应该使用分段对齐策略 小对象则将对齐粒度放小 大对象则放大一些

每次对象的对齐值越大,单次内碎片可能越大,但size_class可能越少,查找越快

自由链表的节点是一个个内存块 头几个字节指向下一个空闲块

这个方法用来对齐

central cache

central cache也是一个哈希桶结构,他的哈希桶的映射关系跟thread cache是一样的。不同的是他的每 个哈希桶位置挂是SpanList链表结构,不过每个映射桶下面的span中的大内存块被按映射关系切成了一 个个小内存块对象挂在span的自由链表中。

申请内存:

1.当thread cache中没有内存时,就会批量向central cache申请一些内存对象,这里的批量获取对象的数量使用了类似网络tcp协议拥塞控制的慢开始算法;central cache也有一个哈希映射的spanlist,spanlist中挂着span,从span中取出对象给thread cache,这个过程是需要加锁的,不过这里使用的是一个桶锁,尽可能提高效率。

2.central cahce映射的spanlist中所有span都没有内存以后,则需要向page cache申请一个新的span对象,那道span以后将span管理的内存按大小切好作为自由链表链接到一起。然后从span中取对象给thread cache

3.central cache中挂的span中use_count记录分配了多少个对象出去,分配一个对象给thread cache,就++use_count

释放内存: 
当thread_cache过长或者线程销毁,则会将内存释放回central cache中的span,释放回来--use_count。当use_count减到0时则表示所有对象都回到了span,则将span释放回page cache,
page cache中会对前后相邻的空闲页进行合并。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值