MongoDB 中的 TCMalloc 内存分配 API 参考:C/C++ 标准内存管理接口详解

发布时间:2026/9/17 15:42:05
MongoDB 中的 TCMalloc 内存分配 API 参考:C/C++ 标准内存管理接口详解 MongoDB 中的 TCMalloc 内存分配 API 参考C/C 标准内存管理接口详解【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongoTCMallocThread-Caching Malloc是 Google 开源的高性能线程缓存内存分配器MongoDB 将其作为核心内存管理组件集成在仓库中。本文以 TCMalloc 官方 API 参考文档为主线系统讲解其提供的 C 与 C 标准内存管理例程malloc()、operator new等的完整语义、对齐规则、失败行为与扩展接口并对照仓库中的头文件与测试代码给出源码级印证帮助你正确使用、替换或分析 MongoDB 底层内存分配行为。TCMalloc 在 MongoDB 项目中的定位TCMalloc 提供 C 和 C 标准库中内存管理例程如malloc()、operator new的实现其源码位于仓库 src/third_party/tcmalloc/dist/。作为第三方依赖被引入 MongoDB 构建体系用于替换 glibc 默认分配器以获得更优的多线程分配性能。从仓库结构看TCMalloc 具备完整独立的实现体系核心实现位于 tcmalloc/tcmalloc.cc公开扩展接口声明于 tcmalloc/malloc_extension.hCoperator new扩展重载则定义在 tcmalloc/new_extension.h 与 tcmalloc/new_extension.cc并配有 tcmalloc/new_extension_test.cc 等测试用例。标准符合性与适用范围TCMalloc 要求调用方代码符合以下标准之一C11C 标准库C API 部分C11 / C14 / C17C 标准库C API 部分需要特别注意的是虽然本文档的 C API 部分使用 C 语言构造如size_t描述但整个 TCMalloc API 设计上都可以直接在 C 代码中调用且预期大部分使用场景来自 C。使用等价 C 构造如std::size_t的调用天然受支持。C APIoperator new/operator deleteTCMalloc 实现了 C11、C14、C17 标准在new头文件中暴露的operator new与operator delete各变体包括基础的::operator new()、::operator delete()及其数组变体C14 引入的带大小参数sized的::operator delete()C17 引入的带对齐参数overaligned的::operator new()与::operator delete()::operator new/::operator new[]变体void* operator new(std::size_t count); void* operator new(std::size_t count, const std::nothrow_t tag) noexcept; void* operator new(std::size_t count, std::align_val_t al); // C17 void* operator new(std::size_t count, std::align_val_t al, const std::nothrow_t) noexcept; // C17 void* operator new[](std::size_t count); void* operator new[](std::size_t count, const std::nothrow_t tag) noexcept; void* operator new[](std::size_t count, std::align_val_t al); // C17 void* operator new[](std::size_t count, std::align_val_t al, const std::nothrow_t) noexcept; // C17对齐语义当未指定__STDCPP_DEFAULT_NEW_ALIGNMENT__或其值大于 8 字节时不带std::align_val_t参数的::operator new使用标准的 16 字节对齐但对于小于 16 字节的分配可能返回对齐要求更低的指针因为该空间内不可能容纳任何需要更大对齐的对象。当以__STDCPP_DEFAULT_NEW_ALIGNMENT__ 8编译时::operator new分配原始存储所使用的大小集合按 8 字节对齐。在许多平台上__STDCPP_DEFAULT_NEW_ALIGNMENT__的值可通过编译选项-fnew-alignment...配置。std::align_val_t变体提供满足所请求对齐要求的存储。失败行为与 C 标准的重要差异如果分配失败程序将直接终止而不会像 C 标准规定的那样抛出异常也不会反复调用std::get_new_handler()尝试重新分配。这种行为的直接好处是对于未标记noexcept的移动构造函数可以让移动操作因分配失败而直接失败从而作为性能优化手段。在 Abseil 代码中这一直接失败行为由构建期配置宏ABSL_ALLOCATOR_NOTHROW启用。如果使用std::nothrow_t变体则分配失败时::operator new返回nullptr而不是终止程序。热冷提示扩展hot_cold_t TCMalloc 的tcmalloc::hot_cold_t变体接受一个hot_cold提示用于表达分配的内存的访问频率预期。该类型为 8 位无符号整数0表示该分配极少被访问255表示该分配被访问得非常频繁TCMalloc 可能利用这些提示进行更好的数据放置与局部性优化。该类型的强类型定义enum class __hot_cold_t : uint8_t与别名tcmalloc::hot_cold_t声明于 tcmalloc/malloc_extension.h并提供了AbslParseFlag/AbslUnparseFlag以便作为 Abseil 标志使用。hot_cold_t变体的operator new重载完整声明于 tcmalloc/new_extension.h覆盖普通、nothrow、对齐__cpp_aligned_new条件下及数组形式void* operator new(size_t size, tcmalloc::hot_cold_t hot_cold) noexcept(false); void* operator new(size_t size, const std::nothrow_t, tcmalloc::hot_cold_t hot_cold) noexcept; void* operator new[](size_t size, tcmalloc::hot_cold_t hot_cold) noexcept(false); void* operator new[](size_t size, const std::nothrow_t, tcmalloc::hot_cold_t hot_cold) noexcept; // #ifdef __cpp_aligned_new 下还有带 std::align_val_t 的四个重载::operator delete/::operator delete[]变体void operator delete(void* ptr) noexcept; void operator delete(void* ptr, std::size_t sz) noexcept; void operator delete(void* ptr, std::align_val_t al) noexcept; void operator delete(void* ptr, std::size_t sz, std::align_val_t all) noexcept; void operator delete[](void* ptr) noexcept; void operator delete[](void* ptr, std::size_t sz) noexcept; // C14 void operator delete[](void* ptr, std::align_val_t al) noexcept; // C17 void operator delete[](void* ptr, std::size_t sz, std::align_val_t al) noexcept; // C17::operator delete/::operator delete[]分别释放对应的::operator new/::operator new[]调用所分配的内存通常作为delete-表达式的一部分被调用。带大小参数的 sized delete 是关键的性能优化它省去了代价高昂的指针 → 大小查找pointer-to-size lookup。C 扩展tcmalloc_size_returning_operator_newTCMalloc 还暴露了提案 P0901 的原型实现声明于 tcmalloc/malloc_extension.htcmalloc::sized_ptr_t tcmalloc_size_returning_operator_new(size_t size);返回值类型tcmalloc::sized_ptr_t是一个同时包含指针与容量信息的结构体struct sized_ptr_t { void* p; size_t n; };该函数分配至少所请求大小的内存返回的n为实际分配容量可能大于请求大小。返回指针满足标准operator new的对齐要求失败时终止程序接受std::nothrow参数的变体在失败时返回{nullptr, 0}。返回的指针必须通过匹配的::operator delete释放。若调用 sized delete则传入的size参数必须介于原始请求大小与实际分配容量之间若两者都不知道可以调用非 sized 的operator delete但这会明显降低效率应尽量避免。该系列还提供了_nothrow、_hot_cold、_aligned等组合变体见 tcmalloc/malloc_extension.h其默认弱实现会使用对应的::operator new(size_t, ...)分配内存。完整实现位于 tcmalloc/tcmalloc.cc 等位置。C API标准库动态内存管理C 标准库在stdlib.h中规定了动态内存管理 API。TCMalloc 实现了以下 C API 函数要求 C11 或更高malloc()calloc()realloc()free()aligned_alloc()对齐保证C90 DR075 与 DR445对于malloc、calloc和reallocTCMalloc 遵循 C90 DR075 和 DR445 规定的行为即使 size 太小而无法容纳任何需要给定对齐的对象对齐要求仍然适用。也就是说malloc(1)返回的指针满足alignof(std::max_align_t)对齐。根据 N2293 的进展未来 TCMalloc 可能会放宽这一对齐保证。此外TCMalloc 还实现了 glibc 中可用的 POSIX 标准库函数posix_memalign()以及 libc 实现中通常提供的以下过时函数仅出于兼容性目的提供不提供文档cfree()memalign()valloc()pvalloc()malloc()void* malloc(size_t size);malloc分配size字节内存并返回指向该内存起始处的void *指针。malloc(0)返回非 NULL 的零大小指针访问该位置是未定义行为。分配失败时返回 NULL。calloc()void* calloc(size_t num, size_t size);calloc()为对象数组分配内存将所有字节零初始化成功后返回指向分配内存块首字节的指针。calloc(num, 0)或calloc(0, size)返回非 NULL 的零大小指针访问该位置是未定义行为。分配失败时返回 NULL。realloc()void* realloc(void *ptr, size_t new_size);realloc()对已有内存区域进行重新分配根据传入的new_size字节数扩展或收缩内存返回指向该内存起始处的void*指针指针可能不变不会对新增内存区域进行任何初始化。realloc(OBJ*, 0)返回 NULL 指针。分配失败时同样返回 NULL。aligned_alloc()void* aligned_alloc(size_t alignment, size_t size);aligned_alloc()以alignment对齐方式分配size字节内存并返回起始指针不进行任何初始化。约束条件size必须是alignment的整数倍alignment必须是 2 的幂。若任一条件不满足aligned_alloc()失败并返回 NULL 指针。aligned_alloc且size0时返回非 NULL 的零大小指针访问该位置是未定义行为。posix_memalign()int posix_memalign(void **memptr, size_t alignment, size_t size);posix_memalign()与aligned_alloc()类似以alignment对齐方式分配size字节指向内存起始处的指针写入**memptr不进行任何初始化。该指针可被转换为所需的数据指针类型以进行解引用。成功时返回0否则返回错误值。与aligned_alloc()的差异在于约束条件alignment必须是sizeof(void *)的 2 的幂倍数。约束不满足时posix_memalign()失败。size0时返回非 NULL 的零大小指针访问该位置是未定义行为。free()void free(void* ptr);free()释放先前由malloc()、calloc()、aligned_alloc()、posix_memalign()或realloc()分配的内存。若传入 NULL 指针函数不做任何事。C 扩展nallocx/sdallocx这两个扩展同样声明于 tcmalloc/malloc_extension.hextern C size_t nallocx(size_t size, int flags) noexcept; extern C void sdallocx(void* ptr, size_t size, int flags) noexcept;nallocx(size_t size, int flags)不实际分配内存但执行与malloc(size)相同的大小计算返回等价的malloc调用实际会得到的分配大小受flags中指定的对齐方式影响。默认的弱实现原样返回sizeTCMalloc 覆盖后返回向上取整后的实际大小。官方注释建议优先使用tcmalloc_size_returning_operator_new而非nallocx因为前者效率更高且能为 TCMalloc 提供更好的遥测数据。sdallocx(void* ptr, size_t size, int flags)释放由malloc或memalign分配的内存通过size参数传入原始分配大小以提升释放性能。默认弱实现调用free()TCMalloc 覆盖后利用 size 参数加速释放路径。源码级行为验证失败与nothrow语义的测试印证tcmalloc/new_extension_test.cc 中的测试用例精确验证了两种失败语义普通hot_cold_t变体在分配失败如超大 size时直接终止进程EXPECT_DEATH(::operator new(kBadSize, hot_cold_t{0}), .*)而带std::nothrow的变体则返回nullptrEXPECT_EQ(::operator new(kBadSize, std::nothrow, hot_cold_t{0}), nullptr)。这印证了参考文档中失败即终止、nothrow变体返回nullptr的行为描述。类型与接口定义位置速查接口/类型声明位置hot_cold_t__hot_cold_t : uint8_ttcmalloc/malloc_extension.hhot_cold_t系列operator new重载tcmalloc/new_extension.htcmalloc_size_returning_operator_new系列tcmalloc/malloc_extension.hsized_ptr_t结构体tcmalloc/malloc_extension.hnallocx/sdallocxtcmalloc/malloc_extension.hoperator new/delete与扩展的实现tcmalloc/tcmalloc.cc行为测试tcmalloc/new_extension_test.cc总结TCMalloc 的 API 覆盖了 C11 与 C11/14/17 标准的全部核心内存管理例程并在标准之上提供了三类实用扩展hot_cold_t热冷提示、tcmalloc_size_returning_operator_new容量返回分配、以及nallocx/sdallocx高性能分配释放接口。理解这些接口的对齐规则、失败语义与性能特性是正确分析 MongoDB 底层内存行为、排查内存问题乃至定制构建的前提。进一步阅读可参考仓库内 TCMalloc 的其他文档quickstart.md快速上手、design.md架构设计、tuning.md调优指南、sampling.md采样机制以及 compatibility.md兼容性说明。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询