文档目录

解决什么问题?

问题:游戏的一帧中需要频繁创建和销毁大量小对象。每次 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 个别对象