数据泄露

围绕将引用传递给生成的线程的主要担忧是“使用后释放”错误:即使用指向已经被释放或取消分配的内存区域的指针来访问数据。 如果你正在使用堆上分配的数据,可以通过告诉Rust你将永远不会回收那部分内存来避免这个问题——你选择故意泄露内存

这可以通过使用Rust标准库中的Box::leak方法来实现,例如:

#![allow(unused)]
fn main() {
// 通过包装在一个`Box`中,在堆上分配一个`u32`。
let x = Box::new(41u32);
// 告诉Rust你将永远不会释放那个堆分配,
// 使用`Box::leak`。这样你就可以得到一个`'static`引用。
let static_ref: &'static mut u32 = Box::leak(x);
}

数据泄露的影响范围是进程级的

泄露数据是危险的:如果你持续泄露内存,最终会耗尽内存并因内存不足而崩溃。

#![allow(unused)]
fn main() {
// 如果让这段代码运行一段时间,
// 它最终会消耗掉所有可用内存。
fn 导致内存溢出() {
    loop {
        let v: Vec<usize> = Vec::with_capacity(1024);
        Box::leak(v);
    }
}
}

同时,通过Box::leak泄露的内存并不是真正被遗忘的。操作系统可以将每个内存区域映射到负责它的进程。当进程退出时,操作系统会回收那些内存。

考虑到这一点,如果满足以下条件,泄露内存是可以接受的:

  • 你需要泄露的内存量不是无限的或预先已知的,或者
  • 你的进程是短暂的,并且你确信在它退出之前不会耗尽所有可用内存

如果应用场景允许,“让操作系统处理它”是一种完全合理的内存管理策略。