当前位置: 首页 > news >正文

021-TCMalloc

TCMalloc

以下是对TCMalloc的技术调研报告,结合原理、代码实现、优化参数及性能对比的综合分析:

一、TCMalloc核心原理

  1. 架构分层
  • TCMalloc采用三级缓存结构,具体流程参考下图:
┌─────────────┐       ┌─────────────┐       ┌─────────────┐ 
│ ThreadCache │──────▶│ CentralHeap │──────▶│  PageHeap   │ 
└─────────────┘       └─────────────┘       └─────────────┘ 
(线程本地缓存)        (全局中央堆)         (系统内存管理)
  • ThreadCache:每个线程独立的小对象缓存(<32KB),无锁操作。
  • CentralHeap:全局共享的中型对象缓存(32KB~256KB),需自旋锁保护。
  • PageHeap:大对象(≥256KB)直接通过mmap分配,按页管理(默认8KB/页)。
  1. 内存管理单元
  • Span:连续内存页的抽象(1~256页),用于记录内存块的分配状态。
struct Span {
  PageID start_page;  // 起始页号 
  size_t num_pages;   // 页数量 
  Span* next;         // 链表指针 
  SizeClass size_class; // 小对象类型 
};

SizeClass:将小对象划分为88种规格(8B~256KB),对齐策略减少碎片。
3. 分配流程

graph TD 
A[分配请求] --> B{对象大小}
B -->|≤32KB| C[ThreadCache]
B -->|>32KB| D[CentralHeap/PageHeap]
C --> E{本地空闲链}
E -->|存在| F[直接分配]
E -->|不存在| G[从CentralHeap补充]
G --> H[拆解Span为小对象]

二、关键代码实现

  1. 核心数据结构
// ThreadCache定义(简化版)
class ThreadCache {
  FreeList list_[kNumClasses]; // 按size class组织的空闲链表 
  void* Allocate(size_t size);
  void Deallocate(void* ptr);
};
 
// CentralHeap中的CentralFreeList 
class CentralFreeList {
  SpinLock lock_;
  SpanList nonempty_; // 非空Span链表 
  SpanList empty_;    // 空Span链表 
};
  1. 分配器入口(Hooking malloc)
extern "C" void* tc_malloc(size_t size) {
  if (size > kMaxSmallSize) {
    return pageheap->AllocLarge(size);
  }
  SizeClass cl = SizeClasser::Classify(size);
  return thread_cache.Get()->Allocate(cl);
}

三、优化参数配置

通过环境变量调整性能(需在程序启动前设置):

  • 限制线程缓存总大小(默认64MB)
export TCMALLOC_MAX_TOTAL_THREAD_CACHE_BYTES=134217728 
  • 内存释放频率(0=不主动释放,1=积极释放)
export TCMALLOC_RELEASE_RATE=0.5 
  • 大对象阈值(默认256KB)
export TCMALLOC_LARGE_ALLOC_REPORT_THRESHOLD=1048576 

完整参数列表可参考Google官方文档 。

四、性能Benchmark对比

  1. 测试代码
#include <benchmark/benchmark.h>
#include <vector>
 
static void BM_Malloc(benchmark::State& state) {
  for (auto _ : state) {
    void* p = malloc(state.range(0)); 
    free(p);
  }
}
BENCHMARK(BM_Malloc)->Arg(64)->Arg(4096)->Arg(1<<20);
 
static void BM_TCMalloc(benchmark::State& state) {
  for (auto _ : state) {
    void* p = tc_malloc(state.range(0)); 
    tc_free(p);
  }
}
BENCHMARK(BM_TCMalloc)->Arg(64)->Arg(4096)->Arg(1<<20);
 
BENCHMARK_MAIN();
  1. 测试结果(单位:ns/op)
分配大小mallocTCMalloc提升比例
64B421564%↑
4KB853262%↑
1MB5204808%↑

数据表明小对象分配性能提升显著。

五、应用建议

  • 适用场景:高频小对象分配(网络协议栈、消息队列)、多线程服务。
  • 陷阱规避:
    避免混合使用不同分配器(如同时链接tcmalloc和jemalloc)
    定期调用MallocExtension::ReleaseFreeMemory()释放闲置内存
  • 监控工具:
MallocExtension::GetInstance()->GetStats(buffer, buffer_size); // 获取内存状态 

完整代码

Github

作者郑天佐
邮箱zhengtianzuo06@163.com
主页http://www.zhengtianzuo.com
githubhttps://github.com/zhengtianzuo

相关文章:

  • embeddings
  • 查看visual studio的MSVC版本的方法
  • 论华为 Pura X 折叠屏性能检测
  • 使用 OpenCV 拼接进行图像处理对比:以形态学操作为例
  • 【Linux网络-NAT、代理服务、内网穿透】
  • 国产开发板—米尔全志T113-i如何实现ARM+RISC-V+DSP协同计算?
  • 深入理解 JavaScript/TypeScript 中的假值(Falsy Values)与逻辑判断 ✨
  • e2studio开发RA4L1(15)----配置RTC时钟及显示时间
  • 阿里云搭建docker私有仓库
  • Ninja编译入门指南:极速构建工具的核心用法与实践
  • NAT 实验:多私网环境下 NAPT、Easy IP 配置及 FTP 服务公网映射
  • 大模型训练的调参与算力调度技术分析
  • 七桥问题与一笔画问题:图论的奠基石
  • 数据库的设计规范:第一范式、第二范式、第三范式
  • 人脸表情识别系统分享(基于深度学习+OpenCV+PyQt5)
  • OpenAI 新语音模型:精细控制AI发声|GPT-4o-transcribe:支持多语言转录,准确率超越Whisper
  • Python第六章07:元组的定义和操作
  • 深入理解 Collections.emptyList():优雅处理空列表的利器!!!
  • 蓝桥与力扣刷题(蓝桥 生日蜡烛)
  • 使用 JDBC 插入数据并获取自动生成的主键(如 MySQL 的 AUTO_INCREMENT 或 Oracle 的序列) 的完整示例代码,包含详细注释
  • 杨文庄当选中国人口学会会长,曾任国家卫健委人口家庭司司长
  • 中国结算澄清“严查场外配资”传闻:账户核查为多年惯例,无特殊安排
  • 诠释微末处的丰盈:“上海制造佳品汇”首届海外专场即将亮相日本大阪
  • 当代科技拟召开债券持有人会议 ,对“H20科技2”进行四展
  • 央媒评网红质疑胖东来玉石定价暴利:对碰瓷式维权不能姑息
  • 硅料收储挺价“小作文”发酵光伏板块罕见大涨,知情人士:确实在谈