1.说明
- 现代很多的开发环境都是多核多线程,在申请内存的场景下,必然存在激烈的锁竞争问题
- malloc本身其实已经很优秀,项目原型tcmalloc就是在多线程高并发的场景下更胜一筹
- 此次实现的内存池需要考虑以下几方面的问题
- 性能问题
- 多线程环境下,锁竞争问题
- 内存碎片问题
2.CMP框架设计
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对象,并且合并相邻的页,组成更大的页,缓解内存碎片的问题
4.内存申请流程
- Size <= 256KB
- 三层缓存
- Size > 256 KB
- 1288K >= Size > 328K
- 直接找Page Cache要内存
- Size > 128*8K
- 直接找系统要内存
- 1288K >= Size > 328K