目录
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位机器的使用,提高设备适配性,