解决什么问题?
问题:游戏的一帧中需要频繁创建和销毁大量小对象。每次 new/delete 调用 malloc,而 malloc 内部用红黑树管理空闲块,有锁竞争,要几十纳秒甚至几微秒。
Arena 的思路:一次性批一大块内存,分配时只做指针加法(1-2 纳秒),释放时整块一起释放。
原理
class Arena {
char* buffer_;
size_t offset_ = 0; // 当前分配到的位置
size_t size_;
public:
Arena(char* buf, size_t sz) : buffer_(buf), size_(sz) {}
void* alloc(size_t bytes) {
if (offset_ + bytes > size_) throw std::bad_alloc();
void* ptr = buffer_ + offset_;
offset_ += bytes;
return ptr;
// 这就是全部了!一条加法指令,约 1ns
}
void reset() { offset_ = 0; } // 整块重置,不用逐个 delete
// 没有 deallocate 方法——Arena 不支持单个释放
};
使用 Arena 的 vector 分配速度:
vector 的 reserve(10000) 使用默认分配器:
malloc(40000) → 内部红黑树查找 64 字节块 → 约 80ns
vector 的 reserve(10000) 使用 Arena 分配器:
buffer_ + offset_ → offset_ += 40000 → 约 2ns
快了 40 倍。
什么时候用 Arena?
| 场景 |
|---|
| 每个请求/每帧/每次 UI 刷新有大量短暂对象 |
| 对象生命周期相同(比如同一帧中创建的,帧结束时全部死亡) |
对延迟敏感,不能承受 malloc 的锁竞争 |
| 什么时候别用 |
|---|
| 对象生命周期参差不齐,无法整块释放 |
需要频繁 delete 个别对象 |