TCmalloc

什么是TCMalloc?它与标准内存分配器有何不同?

传统的内存分配器:

  • 使用全局堆管理,如glibc,malloc
  • 所有内存分配和释放都需要用到全局锁,导致高并发下锁竞争严重
  • 内存碎片管理: 碎片化问题严重
  • 每次操作都需要经过经过全局堆

image

结构

对于memory cache和CentralCach,内部都是维护了不同类型的FreeList
image

image

image

TCMalloc是如何管理内存的?其算法的时间和空间复杂度是多少?

  1. 线程本地缓存
  2. Central free list
    用于管理大块内存以及当线程本地缓存不足时提供内存
  3. page allocator
    管理实际内存页,page allocator从操作系统请求大块内存,然后将其分配给central cache和本地线性缓存
  4. 批量分配
    本地线程需要内存时,它会从central free list一次性获取多块内存,而不是每次只获取一块--->减少锁竞争,提高内存利用率
  5. 回收机制
    当本地线程缓存的某种大小内存块数量超过一定阈值时,多余的内存块会被返回到central free list
  • 分配和释放小块内存时间复杂度O(1),空间复杂度:O(T*S),S是每个线程本地缓存的最大空间
  • 分配和释放大块内存涉及到Page allocator,时间复杂度是O(1),空间复杂度是O(N),其中N是程序所需的总内存

Thread cashing

每个线程都维护一个本地的内存缓存,称为线程本地缓存(Thread Local Cache)。用于存储小块内存,以便线程能快速分配和释放,其效果是减少各线程对全局内存池访问的频率,从而降低了线程间的锁竞争激烈程度。

image

如何使用TCMalloc来分配大块内存?TCMalloc的Large-Object分配器是如何工作的?

Large-Object-Allocator: 专门处理大块内存(通常大于32k)的分配请求

  • 对于大内存分配请求,TCmalloc直接使用mmap系统调用请求内存,避免了中央缓存的复杂管理,提高内存操作效率
  • Huge Page。减少内存碎片,可以使用巨型页(2MB或更大),也是通过mmap实现
  • 使用span,把多个页合并,或者Fragement handling通过把相邻的未使用的span合并得到大内存块,减少内存碎片

TCMalloc是如何避免内存碎片的?内存碎片对应用程序有何影响?

  1. TCmalloc将不同大小的内存块分成不同的类,每个类中的内存块大小相同
  2. Thread Cashing 用于存储和复用本地小块内存
  3. Central Free List,当Thread Cache空闲内存块超过一定值时,多余的内存块会被归还到中央空闲列表,中央空闲列表对不同大小的内存块进行分级管理,确保内存块被高效地回收和再利用。
  4. Page allocator对于大块内存使用span,span分配器会合并相邻的未使用的span,组成更大的span
  5. 动态调整策略:TCmalloc会根据内存使用情况动态调整分配策略。例如,当检测到某个类型的内存块被线程频繁分配和释放,就需要调整该线程的本地缓存大小以减少碎片。

对性能影响:

  • 内存利用率低
  • 内存碎片会增加内存分配和释放的时间
  • 内存不足:当碎片化话严重时,即使系统中有足够的内存,也会因为无法找到足够大的连续内存块而导致分配失败
  • 增大分页频率和CPU缓存命中率低,增加paging频率,导致更多的页表切换和访问磁盘IO。

如何处理线程多并发访问

image

page heap

image

参考

参考

posted @ 2024-05-26 21:54  七块蛋糕  阅读(37)  评论(0编辑  收藏  举报