tcmalloc(高并发内存池)简化版讲解-项目

目录

核心图

内存池是什么

为什么需要内存池

一、申请效率的问题

​编辑

二、内存碎片化

高并发内存池的优势

高并发内存池使用插件

对象池

向上对齐

自由链表

Span

SpanList

基数树

高并发内存池设计

ThreadCache层

CentralCache层

PageCache层

​编辑

切分

合并

锁在内存池有哪些

多线程性能高的重要点


nb.c: 测试仓库 项目代码+图片

核心图


内存池是什么

内存池(Memory Pool) 是一种动态内存分配与管理技术。 通常情况下,程序员习惯直接使用 new、delete、malloc、free 等API申请分配和释放内存,这样导致的后果是:当程序长时间 运行时,由于所申请内存块的大小不定,频繁使用时会造成大量的内存碎片从而降低程序和操作 系统的性能。内存池则是在真正使用内存之前,先申请分配一大块内存(内存池)留作备用,当程序 员申请内存时,从池中取出一块动态分配,当程序员释放内存时,将释放的内存再放入池内,再 次申请池可以 再取出来使用,并尽量与周边的空闲内存块合并。若内存池不够时,则自动扩大内 存池,从操作系统中申请更大的内存池。

为什么需要内存池

一、申请效率的问题

频繁的进入内核态申请内存是不明智的,申请效率大大降低。

例如:我们上学家里给生活费一样,假设一学期的生活费是6000块。

方式1:开学时6000块直接给你,自己保管,自己分配如何花。

方式2:每次要花钱时,联系父母,父母转钱。

同样是6000块钱,第一种方式的效率肯定更高,因为第二种方式跟父母的沟通交互成本太高了。

对堆申请内存也是同样的道理,

二、内存碎片化

碎片化问题非常头痛,在没有内存池的状态下,假设系统依次分配了16byte、8byte、16byte、4byte,还剩余8byte未分配。这时要分配一个 24byte的空间,操作系统回收了一个上面的两个16byte,总的剩余空间有40byte,但是却不能分 配出一个连续24byte的空间,这就是内存碎片问题。

高并发内存池的优势

这里先告诉大家,malloc其实就是一个内存池,他解决了碎片化和效率的问题,在日常的所有是没有问题的,但是在多线程的情况下,malloc函数是一个多线程不安全函数,我们如果在多线程使用malloc就需要每次使用的时候都需要加锁操作,这是十分影响多线程进程的效率。

高并发内存池使用插件

对象池

先理解以下对象内存池,这属于tcmalloc的一个组件,承担管理对象内存申请的对象,不论什么对象,对象池都向系统申请同页大小的内存块,在对象销毁的时候,利用对应对象池回收,并不归还系统中。

对象池的工作流程是,先查看自由链表_freeList查看是否有空闲的内存块,如果有,头删一块给与申请的对象使用。

向上对齐

因为申请的内存不会固定大小,有可能申请1~42亿字节,难道我们需要开这么多个hash映射位吗?这是不切实际的想法,所以当我们申请内存的时候,需要的字节与实际得到的字节是不一样的,比如申请6个字节大小的内存,会得到一个8字节大小的内存块,虽然会浪费2个字节大小,但这是为了效率不得不浪费的内碎片内存问题,无关痛痒,因为在后续为了向上对齐的情况下,最多浪费10%的内碎片字节,让我们看看任何做到的。

为什么最小内存是8个字节呢?我们的内存池必须要适应32位和64位机器的使用,提高设备适配性,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云的小站

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值