为什么我的简易Rust斐波那契程序无法正常退出?
问题原因:Rust自动内存回收导致程序退出延迟
你的带memo HashMap的斐波那契程序并非无法退出,而是清理内存的过程需要额外时间——程序运行10秒内生成了大量超大的BigUint实例并存储在HashMap中,当程序结束时,Rust会自动回收这些对象占用的内存,这个过程耗时约20秒。
两个版本的差异分析
有延迟的递归memo版
这段代码在10秒内会将所有计算过的斐波那契数(从0到i-1)都存储到HashMap中:
use num_bigint::BigUint; use std::collections::HashMap; use std::time::{Duration, Instant}; fn fibonacci(n: usize, memo: &mut HashMap<usize, BigUint>) -> BigUint { match n { 0 => BigUint::from(0u32), 1 => BigUint::from(1u32), _ => { if memo.contains_key(&n) { memo.get(&n).unwrap().clone() } else { let result = fibonacci(n - 1, memo) + fibonacci(n - 2, memo); memo.insert(n, result.clone()); result } } } } fn main() { let start_time = Instant::now(); let mut i = 0; let mut memo: HashMap<usize, BigUint> = HashMap::new(); while start_time.elapsed() < Duration::from_secs(10) { fibonacci(i, &mut memo); i += 1; } println!("The highest Fibonacci number calculated in 10 seconds was Fibonacci({})", i - 1); }
随着i增大,每个斐波那契数的位数会指数级增长,HashMap最终会持有数千个超大数值对象。当main函数结束时,memo的生命周期结束,Rust会遍历HashMap中的所有BigUint实例,逐个释放它们占用的堆内存,这个过程需要大量时间。
无延迟的迭代版
这段代码只维护两个BigUint实例,程序结束时仅需销毁这两个对象,因此几乎瞬间退出:
use num_bigint::BigUint; use std::time::{Instant, Duration}; fn main() { let start_time = Instant::now(); let mut i: usize = 0; let mut fib_prev: BigUint = BigUint::from(0u32); let mut fib: BigUint = BigUint::from(1u32); while start_time.elapsed() < Duration::from_secs(10) { let temp = fib.clone(); fib = fib + &fib_prev; fib_prev = temp; i += 1; } println!("The highest Fibonacci number calculated in 10 seconds was Fibonacci({})", i - 1); }
关于Rust的内存管理
Rust不需要手动管理内存,所有对象的内存都会在其生命周期结束时自动释放。BigUint内部使用堆存储超大数值,HashMap持有所有这些实例的所有权,当memo被销毁时,会触发所有BigUint的Drop操作,逐个释放它们的堆内存。
验证与优化建议
- 验证方式:通过任务管理器观察程序内存占用,打印完结果后内存会逐步下降,直到恢复初始水平后程序才会退出。
- 优化延迟:如果想减少退出耗时,可以在打印结果后手动清空HashMap:
或者改用迭代方式,避免存储所有中间结果。println!("..."); memo.clear(); // 提前触发BigUint的销毁
内容的提问来源于stack exchange,提问作者Kosi
相关产品推荐
相关产品推荐

