本页目录
Allocator 与内存布局
Rust 默认用系统的 malloc/free,但可以通过 GlobalAlloc trait 替换全局分配器或给特定容器指定自定义分配器。Layout 描述内存的大小和对齐,Pin 保证值不可移动(对自引用类型和异步 Future 至关重要),
#[repr(align)]和#[repr(C)]精确控制内存布局。
默认分配器
Rust 默认用系统的 malloc/free(glibc 的 ptmalloc2 on Linux),但可以替换。实现 GlobalAlloc trait 并标记 #[global_allocator]:
use ;
;
unsafe
static GLOBAL: MyAllocator = MyAllocator;
常用替代分配器:mimalloc(Microsoft,低碎片)、jemalloc(FreeBSD,多线程优化)、snmalloc(Microsoft Research,message-passing based)。
Layout: 分配请求的描述
分配器不直接接收"给我 N bytes"——而是接收 Layout 结构,包含大小和对齐:
use Layout;
let layout = ; // size=8, align=8
let layout2 = from_size_align.unwrap;
分配器必须返回满足对齐要求的内存。如果分配失败,返回 null(不是 panic)。
allocator API: 手动分配
use ;
let layout = ;
let ptr = unsafe ;
unsafe ;
unsafe ;
这几乎是 C 的 malloc/free,加了类型安全的 Layout 参数。绝大多数代码不需要直接调 alloc——Box, Vec, String 等已处理。
Pin: 保证不被移动
Rust 的 move semantics 意味着任何值都可以被 memcpy 到新地址。但对于自引用结构(struct 的字段引用同一个 struct 的另一个字段),move 后引用变成悬垂。Pin 保证 pinned 的值不会再被 move:
use Pin;
// 典型的自引用结构 (简化):
// 构造时 ptr 指向 value, 但如果 SelfRef 被 move → ptr 悬垂
// Pin<Box<SelfRef>> 保证 SelfRef 不会被 move — 安全
async fn 生成的 Future 是典型的自引用结构——它引用了 await 点之前的局部变量。Pin<&mut Future> 保证在 poll 期间 Future 不会被 move。这是 async/await 编译器的内部实现基础。
参考
- Rustonomicon: Allocator, Pin
- RFC 1398: Custom allocators
- RFC 2349: Pin
Keywords: GlobalAlloc, Layout, custom allocator, Pin, self-referential, #[repr(align)], alloc API