使用Massif用valgrind测量时,Rust程序的堆大小非常大

Red*_*ain 2 valgrind rust massif

我正在尝试测量正在编写的rust程序的内存大小。我注意到当我使用以下命令测量堆大小时:

valgrind --tool=massif --pages-as-heap=yes ./program

并使用ms_print测量,内存大小非常大(通常约为16MB)。最终,我将rust程序简化为一个空的main函数:

fn main() {
}
Run Code Online (Sandbox Code Playgroud)

我编译后,仍然有16MB的内存大小。我注意到当我使用另一台计算机时,相同的二进制文件总大小为4MB。我的一位朋友在他的计算机上使用相同的程序尝试了此操作,并使用了相同的rust / valgrind版本,并且还获得了4MB的大小。

我想象这是可能在堆中使用的某种预分配内存,但是我无法找到任何控制它的方法。我什至尝试按照指南更改分配器,但没有任何更改。

系统细节:

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
Run Code Online (Sandbox Code Playgroud)

Séb*_*uld 6

pages-as-heap由于大多数现代操作系统(尤其是linux)上的页面管理工作方式的误解,导致您出错的地方是。这不会是所有的平台真正的并取决于分配器,底层平台和MMU。在实践中,如果平台支持虚拟内存,则很可能会有类似的东西。

页面并非始终是内存中的强制保留区域。大多数内存功能(和mmapmalloc以及其他一些内存功能)将分配内存,但这仅被操作系统/内核认为是指示性的。您可以通过以下测试使自己相信这一点:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  void *ptr = malloc(1024 * 1024 * 1024);
  sleep(100);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行几次,然后...

:~# 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
Run Code Online (Sandbox Code Playgroud)

您可以在中复制此测试rust,但是您需要比通常在抽象中进行的测试稍低一些以实现此目的:

fn main() {
  let mut vec:Vec<u8> = vec![];
  vec.reserve(1024 * 1024 * 1024);
}
Run Code Online (Sandbox Code Playgroud)

内存只有在初始化访问后才有意义。到那时,操作系统知道您确实需要它,并一直将其分配给硬件。Rust也不例外-在使用某些堆之前,该堆只是mmap内核中指向虚拟内存的a。

这样,通过使用pages-as-heap参数,您仅在完成任何重新分配之前查找“潜在”内存,而不是实际使用的内存。删除此参数,您将看到程序消耗300字节左右的堆(您可以轻松地对其进行分析valgrind)。

您的朋友看到​​不同输出的原因是因为他们的页面大小为4kB,而您的页面大小为16kB。稍后,我将在rustc源代码中查找确切点-rust分配1024页。