我正在尝试测量正在编写的rust程序的内存大小。我注意到当我使用以下命令测量堆大小时:
valgrind --tool=massif --pages-as-heap=yes ./program
并使用ms_print测量,内存大小相当大(最初约为16MB)。最终,我将rust程序简化为一个空的main函数:
fn main() {
}
然后我进行编译,并且 still 的内存大小为16MB。我注意到当我使用另一台计算机时,相同的二进制文件总大小为4MB。我的一位朋友在他的计算机上使用相同的程序尝试了此操作,并使用了相同的rust / valgrind版本,并且还获得了4MB的大小。
我想这是对内存的某种预分配,可能会在堆中使用,但是我想不出任何方法来控制它。我什至尝试按照this指南更改分配器,但没有任何改变。
系统详细信息:
OS version = Ubuntu 18.04
valgrind version = valgrind-3.13.0
cargo version = cargo 1.39.0-nightly (3f700ec43 2019-08-19)
rustc version = rustc 1.39.0-nightly (e44fdf979 2019-08-21)
ms_print = ms_print-3.13.0
libc version = ldd (Ubuntu GLIBC 2.27-3ubuntu1) 2.27
答案 0 :(得分:6)
导致误解的地方是pages-as-heap
,这是由于对大多数现代操作系统(尤其是linux)上的页面管理工作方式的误解。 并非在所有平台上都是正确的,并且取决于分配器,基础平台和MMU。实际上,如果您的平台支持虚拟内存,则很可能会有类似的东西。
页面在内存中并不总是被强制保留的区域。大多数内存功能(mmap
,malloc
和其他几个功能)都会分配内存,但这仅被操作系统/内核认为是指示性的。您可以通过以下测试使自己信服:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
void *ptr = malloc(1024 * 1024 * 1024);
sleep(100);
return 0;
}
运行几次,然后...
:~# free -m
total used free shared buff/cache available
Mem: 15930 1716 5553 170 8661 13752
Swap: 0 0 0
:~# ./hog &
[1] 27577
...
[99] 27674
:~# free -m
total used free shared buff/cache available
Mem: 15930 1717 5552 170 8661 13751
Swap: 0 0 0
您可以在rust
中复制此测试,但是您需要比通常为实现这一目标而进行的抽象稍低一些:
fn main() {
let mut vec:Vec<u8> = vec![];
vec.reserve(1024 * 1024 * 1024);
}
只有在初始化并访问后,内存才有意义。到那时,操作系统知道您确实需要它,并一直将其分配给硬件。 Rust也不例外-在使用某些堆之前,该堆只是内核中指向虚拟内存的mmap
。
这样,通过使用pages-as-heap
参数,您只是在完成任何重新分配之前寻找“潜在”内存,而不是使用的 actual 内存。删除此参数,您将看到程序消耗300字节左右的堆(您可以使用valgrind
本身轻松地对其进行分析)。
您的朋友看到不同输出的原因是因为他们的页面大小为4kB,而您的页面大小为16kB。稍后,我将在rustc源代码中查找确切点-rust分配1024页。