mimalloc vs tcmalloc 实现对比:结构关系、分配与回收
这是一篇面向工程实践的内存分配器实现对比文章。你会先建立的统一心智模型文章先统一了 Reserve、Commit/Decommit、Container、Owner、Cache 这组术语,避免比较时“同词不同义”。mimalloc 被刻画为“显式 commit 记账 + owner page”,tcmalloc 被刻画为…
mimalloc vs tcmalloc 实现对比:结构关系、分配与回收 面向开发者。本篇按“结构关系 → 数据流 → 回收与 RSS → 碎片化 → trade‑off”的顺序组织,力求像技术书籍一样连贯叙述,而不是简单列举参数与路径。所有关键结论均可在 Code Index 中找到对应源码行号。 Code snapshot:mimalloc: tmp/mimalloc/ git describe v2.2.7-9-gb69f9cb3tcmalloc: tmp/tcmalloc/ git describe 47a88fac1. 术语与核心定义 这两套 allocator 都在“虚拟地址空间”上开疆拓土,但掌控方式不同:mimalloc 更像是“自己记账并控制 commit”,tcmalloc 更像是“依赖 OS 按需提交并用 madvise 回收”。以下术语用于统一描述。Reserve: 向 OS 预留大块虚拟地址空间Commit / Decommit: 虚拟页是否映射到物理内存mimalloc: commit mask 显式跟踪与执行tcmalloc: 依赖 OS 按需提交 + madvise/munmap 归还Container: allocator 级别的回收粒度mimalloc: page(由 1..N 个 slice 组成)tcmalloc: span(由若干 tcmalloc page 组成)Owner: 容器级别归属mimalloc: page 归属某个 heap/threadtcmalloc: object 无 owner,span 由 central/pageheap 管理Cache: 快路径缓存层mimalloc: page freelisttcmalloc: per‑CPU / ThreadCache / TransferCache2. mimalloc:结构关系与数据流2.1 结构关系图(字符画)mimalloc segment (32MiB) └─ slices (64KiB) └─ page (1..N slices) └─ size class (page->block_size 固定) └─ blocks (objects) 2.2 结构解释 mimalloc 的世界从 segment 开始。它先在虚拟地址空间中预留一个 32MiB 的段,然后把段切成 64KiB 的 slice。page 是 slice 的组合体,page 上的 block_size 固定,于是 page 就天然“绑定”了一个 size class。对象(block)从 page 的 freelist 弹出,page 为空时才能走回收路径。segment / slice / page 的尺寸:MI_SEGMENT_SIZE=32MiB,MI_SEGMENT_SLICE_SIZE=64KiB,small page = 64KiB,medium page = 512KiBcommit 粒度:MI_COMMIT_SIZE == MI_SEGMENT_SLICE_SIZE,commit mask 在 slice 粒度上记账page 与 size class:mi_page_t::block_size 固定,page 队列按 size class 管理2.3 分配数据流(快路径) mimalloc 的分配路径极短:根据 size 直接落到 pages_free_direct;拿到 page 后从 freelist pop 一个对象。flowchart LR A[size] -->|1 map size| B[pages_free_direct] B -->|2 get page| C[mi_page_t] C -->|3 pop free list| D[object] 2.4 free 与跨线程回收 mimalloc 的关键设计是 owner page。page 的 freelist 只由 owner 线程维护,跨线程 free 不能直接触碰 freelist,于是走“原子挂链 + 延迟合并”的路径:flowchart LR A[free object] -->|1 local free| B[page free] A -->|2 remote free| C[xthread_free] C -->|3 owner collect| B 这解释了 mimalloc 的低延迟:跨线程 free 只是一次 CAS,真正的合并留给 owner 在合适时机完成。2.5 OS 归还路径 page 空了只是“可回收”,但不必然立即归还 OS。mimalloc 会标记 purge,再在 collect 阶段真正触发 decommit/madvis…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行