ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

malloc arena

2026/9/6 5:19:45 拓冰建站 浏览量
malloc arena ptmalloc2 为了支持多线程而设计的核心架构——Arena。它可以说是整个分配器的“战场”和“资源池”。可以把 Arena 理解为一个完全独立的内存“王国”每个王国都有自己的堆内存、自己的各种 Bin空闲链表、自己的锁以及自己的 Top Chunk。多线程环境下不同线程可以同时操作不同的 Arena从而实现并发分配减少锁竞争。1. 什么是 Arena为什么需要它在早期的dlmalloc中整个进程只有一个堆所有线程的malloc/free操作都需要竞争一个全局锁。这在多核时代显然会成为性能瓶颈。Arena 的出现就是为了解决这个问题。它的核心思想是资源隔离每个 Arena 管理自己独立的内存区域一个或多个连续的堆段。并发分配线程可以尝试获取一个专属的 Arena之后的内存分配和释放主要在这个 Arena 内进行从而减少了与其他线程竞争全局锁的概率。数量限制Arena 的数量并不是无限的。在 64 位系统上通常为CPU 核心数的 8 倍。这是为了在并发性能和内存开销之间取得平衡。2. Arena 的类型ptmalloc2 管理着两种类型的 Arena主 ArenaMain Arena这是进程启动时由 Glibc 自动创建的 Arena。它使用的堆内存是通过brk/sbrk系统调用扩展的即传统的 program break 方式。主 Arena 只有一个其结构体是全局变量。非主 ArenaThread Arena当主 Arena 被占用且新的线程请求分配内存时ptmalloc2 可能会创建一个新的 Arena。非主 Arena 的堆内存是通过mmap系统调用从操作系统映射的匿名内存段。一个 Arena 可以管理多个mmap映射的堆段这些堆段通过链表连接在一起。3. Arena 的内部结构宏观视角每个 Arena 结构体malloc_state都包含的所有核心组件锁mutex保护 Arena 内部数据结构Bins、Top Chunk 等的互斥锁防止多线程同时修改。Bins 数组包括fastbinsYFastbins、binSmall/Large Bins 的数组以及unsorted bin。Top Chunk 指针指向当前 Arena 堆顶部的可用内存块。Heap 信息对于非主 Arena会有一个链表记录其管理的所有heap_info结构每个heap_info描述一个通过mmap映射的堆段。统计信息如已分配的内存总量、可回收的内存等。4. Arena 的分配与调度策略它是如何工作的当一个线程首次调用malloc时ptmalloc2 会按以下逻辑为其分配 Arena尝试获取已存在的 Arena系统会遍历一个全局的 Arena 链表尝试找到一个未被锁定的 Arena。如果找到则将其分配给当前线程线程与 Arena 之间会建立关联以提高后续操作的局部性。创建新的 Arena如果允许如果所有 Arena 都被锁定并且当前 Arena 总数未达到上限narenasptmalloc2 会创建一个新的 Arena并将其分配给当前线程。阻塞等待如果达到上限如果 Arena 总数已达到上限并且所有 Arena 都在被其他线程使用当前线程就会阻塞等待某个 Arena 被释放即等待其锁被释放。这与 “锁” 的行为一致。一个重要的细节是线程与 Arena 的绑定关系并非永久性的。当线程释放其 Arena 的锁后其他线程可以抢到这个 Arena。这种机制确保了 Arena 资源在繁忙线程间能得到充分利用。5. 关键特性与注意事项Arena 是内存增长的“边界”每个 Arena 都有自己的 Top Chunk其堆空间的增长是独立的。主 Arena 受限于程序 break 的单一位置而非主 Arena 的多个堆段则可以通过mmap在虚拟地址空间中分散分布。内存无法跨 Arena 归还一个 Arena 无法归还另一个 Arena 的内存。如果一个线程在其 Arena 中分配了大量内存并释放这些内存会留在该 Arena 的空闲链表中只会被该 Arena 自身重用不会给其他 Arena 使用。这可能导致内存闲置一个 Arena 中缓存了大量空闲内存而另一个 Arena 却因空间不足需要向操作系统申请新内存。Arena 的“附加”与“脱离”当通过mmap为 Arena 扩展堆段时新的堆段会附加到 Arena 的堆段链表中。当堆段顶部完全空闲时即 Top Chunk 位于该堆段且足够大该堆段可能被munmap脱离并释放回操作系统。对调试的影响在多线程程序中观察到内存分配时需要意识到可能有多个 Arena 存在。使用gdb的info malloc-stats或特定malloc_stats()函数打印的信息时会看到每个 Arena 的独立统计。总结Arena 是 ptmalloc2 多线程能力的基石它通过资源隔离和锁粒度细化显著减少了多线程内存分配时的锁竞争提升了程序在大型多核服务器上的性能和可扩展性。每个 Arena 都是一个功能完备的小型内存分配器拥有自己独立的 Bin 和 Top Chunk。它的调度策略在性能避免等待和内存使用率限制创建数量之间取得了微妙的平衡。