LLVM Arena 通常指的是 LLVM 中基于“arena allocation(区域分配)”思想的内存管理方式。这种方式在编译器、AST、IR 等大量小对象频繁创建的场景中非常常见,可以显著提升性能。

LLVM 中虽然没有一个统一叫 Arena 的类,但有几种典型实现,例如:

  • llvm::BumpPtrAllocator
  • llvm::SpecificBumpPtrAllocator
  • llvm::RecyclingAllocator

其中 BumpPtrAllocator 就是 LLVM 的 arena allocator 的核心实现

1. 什么是 Arena Allocation

**Arena(区域分配)**是一种非常简单高效的内存分配策略:

核心思想:

申请一大块内存
      ↓
对象从这块内存顺序分配
      ↓
不单独 free
      ↓
整个 arena 一次性释放

普通 new/delete 的问题

  • 分配开销大
  • 内存碎片
  • malloc/free 频繁

Arena Allocation 特点:

  • 只移动指针
  • 不单独释放对象
  • 整体释放
Arena memory block
+--------------------------------------+
| obj1 | obj2 | obj3 | obj4 | obj5 ... |
+--------------------------------------+
        ↑ bump pointer

时间复杂度:

alloc = O(1)
free  = O(1)  (整体释放)

2. LLVM 为什么需要 Arena

LLVM 有大量 短生命周期小对象,例如:AST,IR

特点:数量巨大,生命周期接近,很少单独删除

如果用 new/delete:malloc/free 非常慢,内存碎片严重,所以 LLVM 采用 Arena allocator

3. LLVM 的 BumpPtrAllocator

LLVM 的核心 Arena:llvm::BumpPtrAllocator

原理:

memory block
+--------------------------------+
| allocated objects ...          |
+--------------------------------+
                               ↑
                           bump pointer

分配时:ptr += size,如果 block 不够,再申请一个新的 block

代码示例

#include "llvm/Support/Allocator.h"
 
llvm::BumpPtrAllocator allocator;
 
int *a = allocator.Allocate<int>();
*a = 10;
 
double *b = allocator.Allocate<double>();
*b = 3.14;

特点:

  • 不调用构造函数
  • 只分配 raw memory

如果要构造对象:

MyClass *obj = new (allocator.Allocate<MyClass>()) MyClass();

这是 placement new

4. LLVM Arena 内存结构

LLVM 实际结构:

BumpPtrAllocator
     │
     ├── Slab1 (4KB / 8KB / ...)
     │      obj obj obj obj
     │
     ├── Slab2
     │      obj obj obj
     │
     └── Slab3

当一个 slab 用完:new slab

优点:

  • 分配速度极快
  • cache locality 好
  • 几乎无碎片

5. 释放内存

Arena 的释放方式:reset

效果:所有对象一起释放,类似:free(arena)

6. Arena vs shared_ptr

Arena 和智能指针思路完全不同

特性Arenashared_ptr
释放整体引用计数
开销极低较高
生命周期批量单对象
用途编译器通用

编译器通常用 Arena + raw pointer,而不是 shared_ptr,因为 shared_ptr 太慢

7. 为什么 LLVM 不用 GC

Arena 其实是 简化版 GC:不跟踪对象,不回收单对象,只整体回收

优点:实现简单,性能极高