内存分配器概述&对比ptmalloc和tcmalloc

关于内存分配器ptmalloc以及tcmalloc的详细讲解:

内存分配器------彻底理解tcmalloc

内存分配器------彻底理解ptmalloc


为什么要有内存管理

因为brk、sbrk、mmap都属于系统调用,若每次申请内存,都调用这三个,那么每次都会产生系统调用,影响性能;其次,这样申请的内存容易产生碎片,因为堆是从低地址到高地址,如果高地址的内存没有被释放,低地址的内存就很难被回收(当然,共享区没有这个限制)。因此内存管理其实有两个作用:

  • 优化性能
  • 缓解内存碎片问题(一方面是管理并复用brk产生的碎片,一方面解决内存池为了性能本身把内存分块管理造成的碎片问题)

内存管理概述

内存管理分为用户程序层、C 运行时库层、内核层三个层面,其中分配器 allocator 属于 C 运行时库的内存管理模块,它负责响应用户程序的内存分配请求,再向内核申请内存并返回给用户;为提升分配效率,allocator 通常会预先申请一块远超用户需求的内存自行管理,用户释放的内存也不会立即还给操作系统,而是由 allocator 统一维护空闲内存块,后续有新分配需求时会优先从空闲空间中匹配合适内存,匹配不到才再向内核申请新内存,业界主流的内存分配器有 glibc 默认标配的 ptmalloc、Google 的 tcmalloc 以及 Facebook 的 jemalloc。


ptmalloc与tcmalloc对比

  1. 线程并发处理
    • ptmalloc:通过将内存分为多个分配区(arena)来缓解多线程锁竞争,但分配区数量有限,且一个分配区可能被多个线程共享,因此在高并发下仍存在性能瓶颈。
    • tcmalloc:为每个线程分配一个 threadCache,实现无锁的内存申请和释放,大幅提升并发性能。
  2. 内存局部性优化
    • ptmalloc:使用 last remainder chunk 来提升局部性,效果不确定。
    • tcmalloc:每个线程几乎总是从同一个 Span 切割同大小内存块,自然具备更好的局部性,对连续小块内存分配更高效。
  3. 内存占用
    • ptmalloc:内存占用不是特别多,因为分配区是有限的。但是****长时间运行容易出现内存暴增,因为只有靠近 top chunk 的内存块被释放时才会触发缩容。
    • tcmalloc:内存占用很多,因为每个线程都要有一份ThreadCache以及其中的各种类型的内存块
  4. 小块内存合并
    • ptmalloc:合并小块内存时,总是需要向前向后遍历空闲块,操作相对较慢。
    • tcmalloc:小块内存合并非常快且自然,只需对应 Span 的计数器减减即可。
  5. 资源调度与忙闲不均
    • ptmalloc:无法合理处理线程使用不均的情况。例如,线程 A 频繁申请内存,线程 B 几乎不申请,B 却浪费了分配区资源。
    • tcmalloc:使用 centralCache 进行线程间的合理调度,避免资源浪费。 ​​​​​​​

总结

ptmalloc 适合通用、线程数不极端的环境,无明显偏好,兼容性最好。

tcmalloc 在多线程高并发、频繁分配/释放大量小对象的场景下优势显著(如果频繁),尤其适合对延迟敏感以及内存消耗不敏感的服务。

相关推荐
YYYing.12 天前
【C++项目之高并发内存池 (一)】项目介绍与定长内存池的构建
项目·c/c++·内存池·池化技术
洛水水16 天前
图解式讲解内存池:告别内存碎片与随机coredump
linux·内存池
洛水水19 天前
KVStore 内存池实战:从实现到应用,告别 malloc 焦虑
网络·内存池
楚国的小隐士1 个月前
为什么说Rust是对自闭症谱系人士友好的编程语言?
java·rust·编程·对比·自闭症·自闭症谱系障碍·神经多样性
雪碧聊技术2 个月前
Vue UI 组件库综合对比
ui组件库·对比
卷卷的小趴菜学编程3 个月前
项目篇----使用基数树对性能进行优化
算法·tcmalloc
卷卷的小趴菜学编程3 个月前
项目篇----仿tcmalloc的内存池设计(内存回收)
前端·后端·html·tcmalloc·内存池
春夜喜雨3 个月前
关于内存分配的优化与设计
c++·tcmalloc·malloc·jemallc
卷卷的小趴菜学编程3 个月前
项目篇----仿tcmalloc的内存池设计(page cache)
c++·缓存·单例模式·tcmalloc·内存池·span cache