深入 Rust 内存模型:从栈帧到堆分配

深入 Rust 内存模型:从栈帧到堆分配

Rust 的所有权系统在语言层面保证了内存安全,但理解底层的内存布局对于编写高性能代码同样重要。本文从汇编层面深入分析 Rust 的内存模型。

栈帧布局分析:

示意图
示意图
struct Point {
    x: f64,
    y: f64,
}

fn process(p: Point) -> f64 {
    p.x * p.x + p.y * p.y
}

// 编译后的汇编(x86_64)
// process:
//     movsd   xmm2, xmm0     ; x
//     mulsd   xmm2, xmm0     ; x * x
//     movsd   xmm3, xmm1     ; y
//     mulsd   xmm3, xmm1     ; y * y
//     addsd   xmm2, xmm3     ; x*x + y*y
//     movapd  xmm0, xmm2     ; 返回值
//     ret

自定义全局分配器:

use std::alloc::{GlobalAlloc, Layout, System};

struct TrackingAllocator;

unsafe impl GlobalAlloc for TrackingAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        let ptr = System.alloc(layout);
        if !ptr.is_null() {
            // 记录分配信息
            ALLOC_TRACKER.track(layout.size(), ptr);
        }
        ptr
    }

    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        ALLOC_TRACKER.untrack(ptr);
        System.dealloc(ptr, layout);
    }
}

#[global_allocator]
static GLOBAL: TrackingAllocator = TrackingAllocator;

Rust 的枚举在内存中的表示也值得深入研究。Option<Box<T>> 利用空指针优化,与裸指针占用相同的内存。而普通的 Option<&T> 同样利用引用的非空保证实现了零开销的 None 表示。理解这些底层细节,可以帮助你在性能敏感场景做出更好的数据结构选择。