LLVM Arena 通常指的是 LLVM 中基于“arena allocation(区域分配)”思想的内存管理方式。这种方式在编译器、AST、IR 等大量小对象频繁创建的场景中非常常见,可以显著提升性能。
LLVM 中虽然没有一个统一叫 Arena 的类,但有几种典型实现,例如:
llvm::BumpPtrAllocatorllvm::SpecificBumpPtrAllocatorllvm::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 和智能指针思路完全不同
| 特性 | Arena | shared_ptr |
|---|---|---|
| 释放 | 整体 | 引用计数 |
| 开销 | 极低 | 较高 |
| 生命周期 | 批量 | 单对象 |
| 用途 | 编译器 | 通用 |
编译器通常用 Arena + raw pointer,而不是 shared_ptr,因为 shared_ptr 太慢
7. 为什么 LLVM 不用 GC
Arena 其实是 简化版 GC:不跟踪对象,不回收单对象,只整体回收
优点:实现简单,性能极高