我正在处理大量Rust 的数据,在判断数据 struct 的内存使用情况时,我偶然发现了一些令人惊讶的结果.
首先,我试着手动填充一个向量,只需将其按零即可:
let mut arr = vec![];
for _ in 0..(4_294_967_294 as u32) {
arr.push(0);
}
过了一会儿,我很期待地说,我的计算机耗尽了可用内存,进程被操作系统终止.
但是,如果我使用宏初始化来初始化向量,行为会发生变化:
let mut arr = vec![0; 2_147_483_647_000];
for i in 1..1_000_000_000 {
arr[i-1] = rng.next_u64();
let sample = rng.next_u32();
let res = arr[sample as usize];
if i % 10000000 == 0 {
print!("After {} ", i);
print!("Btw, arr[{}] == {} ", sample, res);
print_allocated_memory();
}
}
尽管我用一个实际的u64值填充了10亿个条目,并从数组中读出了随机值(主要是零,我只是试图排除编译器对整个数组的优化),但我的计算机内存并没有溢出.
每jemalloc
个内存使用率如下(请注意,我的电脑只安装了16 GB的RAM):
allocated 16777216.05 MiB resident 16777223.02 MiB
... 而我的操作系统在代码末尾报告的最大值约为8000米(以htop为单位).
奇怪的是,如果我使用0以外的任何其他默认值(无论是1还是100),宏在完成向量创建之前就会耗尽内存,因此它肯定与init值为0有关.
我想知道宏做了什么来保持结果数据 struct 的内存效率?数组中的元素不是真的创建的吗?如果没有,那么我如何从向量中读出随机指数呢?
我已经判断了documentation,尽管它只说它依赖于Clone
类型的默认元素,这对基本类型来说并没有任何意义.