Pony 的 Arena 分配器:让每线程追踪自己的内存,治愈无界增长
来源:ponylang.io — 2026-08
📋 概述
Pony 团队在把 TCP 压力测试加上「群涌式随机化」后,挖出一堆真 Bug,其中之一就是分配器的内存无界增长。旧的全局池式分配器因不追踪「谁分配了这块内存」,导致跨线程释放、不同尺寸槽、相邻空闲块合并三方面全部失效。新分配器借鉴 snmalloc 的区域化设计:每线程认领自己的 arena,跨线程释放分批路由给所有者,内存空置后归还 OS。测试中 1GiB 工作集在空闲后从 1,025MiB 回落到 27MiB。
🔑 核心要点
- 旧分配器的三大病灶:跨线程释放永不回收、32 字节槽被占用、相邻空闲块永不合并。
- 新设计按 snmalloc 区域化思路:每线程专属 arena,内存何时空、何时还由所有者掌握。
- arena 基址按自身大小对齐,一次位掩码即可定位归属,无需读内存。
- 单位使用 bitmap 表示空闲/占用,相邻空闲天然是连续区间,无需合并逻辑、无 O(n) 遍历。
- 跨线程释放分批路由给所有者,加每线程缓存,把多次原子操作降为一次。
- 空闲线程定时归还所有内存:1GiB 工作集空闲后从 1,025MiB 降至 27MiB,旧分配器一直锁着 1,019MiB。
💡 金句
内存相邻即 bitmap 相邻,bitmap 相邻即一个连续区间——从来就是如此,只是旧的表示法不允许它发生。
👍 0
👎 0
← 返回 Lobsters 首页