Размер кучи для программ Rust очень большой при измерении с помощью valgrind с использованием массива - PullRequest
2 голосов
/ 19 сентября 2019

Я пытаюсь измерить объем памяти программы ржавчины, которую я пишу.Я заметил, что когда я измеряю размер кучи с помощью команды:

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

и измеряю с помощью ms_print, размер памяти был довольно большим (изначально около 16 МБ).В конце концов, я сократил свою программу ржавчины до пустой основной функции:

fn main() {
}

И я скомпилировал, а все еще имел размер моей памяти 16 МБ.Я заметил, что при использовании другой машины тот же самый двоичный файл будет иметь общий размер 4 МБ.Один из моих друзей попробовал это с той же самой программой на своем компьютере, с той же версией 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

1 Ответ

6 голосов
/ 19 сентября 2019

Место, которое приводит вас к ошибке - 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,вы ищете только «потенциальную» память до того, как будет выполнено какое-либо перераспределение, а не используемую фактическую память.Удалите этот параметр, и вы увидите, что ваша программа потребляет около 300 байтов кучи (которую вы можете легко проанализировать с помощью valgrind).

Причина, по которой ваши друзья видят другой вывод, заключается в том, что их размер страницы4 КБ, а ваш 16 КБ.Я отследю точную точку в исходном коде rustc позже - rust выделяет 1024 страницы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...