Jak inni słusznie zauważyli, trudno jest uzyskać kontrolę nad rzeczywistą pamięcią używaną przez proces, co ze współdzielonymi regionami i plikami mmap i tym podobne.
Jeśli jesteś eksperymentatorem, możesz uruchomić valgrind i masyw . Może to być nieco ciężkie dla zwykłego użytkownika, ale z czasem zorientujesz się, jak zachowuje się pamięć aplikacji. Jeśli malloc () aplikacji jest dokładnie tym, czego potrzebuje, to da ci dobrą reprezentację rzeczywistego dynamicznego wykorzystania pamięci przez proces. Ale ten eksperyment można „zatruć”.
Aby komplikować sprawy, Linux pozwala przesadzić z pamięcią. Kiedy robisz pamięć malloc (), deklarujesz zamiar wykorzystania pamięci. Ale tak naprawdę alokacja nie następuje, dopóki nie zapiszesz bajtu na nowej stronie przydzielonej „pamięci RAM”. Możesz to sobie udowodnić, pisząc i uruchamiając mały program w taki sposób:
// test.c
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>
int main() {
void *p;
sleep(5)
p = malloc(16ULL*1024*1024*1024);
printf("p = %p\n", p);
sleep(30);
return 0;
}
# Shell:
cc test.c -o test && ./test &
top -p $!
Uruchom to na maszynie z mniej niż 16 GB pamięci RAM i, voila !, właśnie zdobyłeś 16 GB pamięci! (nie, nie bardzo).
Zauważ, top
że widzisz „VIRT” jako 16,004G, ale% MEM to 0,0
Uruchom to ponownie z valgrind:
# Shell:
valgrind --tool=massif ./test &
sleep 36
ms_print massif.out.$! | head -n 30
A masyw mówi „suma wszystkich allocs () = 16 GB”. To nie jest bardzo interesujące.
ALE, jeśli uruchomisz go przy zdrowym procesie:
# Shell:
rm test test.o
valgrind --tool=massif cc test.c -o test &
sleep 3
ms_print massif.out.$! | head -n 30
--------------------------------------------------------------------------------
Command: cc test.c -o test
Massif arguments: (none)
ms_print arguments: massif.out.23988
--------------------------------------------------------------------------------
KB
77.33^ :
| #:
| :@::@:#:
| :::::@@::@:#:
| @:: :::@@::@:#:
| ::::@:: :::@@::@:#:
| ::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| @::@:::@:::::@:: :::@@::@:#:
| :@@@@@@@@@@@@@@@@@@@@:@::@:::@:::::@:: :::@@::@:#:
| :@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| :::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
| ::::::::@::::@@:@@ :@::@:::@:::::@:: :::@@::@:#:
0 +----------------------------------------------------------------------->Mi
0 1.140
I tutaj widzimy (bardzo empirycznie iz dużą pewnością), że kompilator przydzielił 77 KB sterty.
Po co tak bardzo starać się o wykorzystanie sterty? Ponieważ wszystkie współdzielone obiekty i sekcje tekstowe używane przez proces (w tym przykładzie kompilator) nie są strasznie interesujące. Są stałym kosztem procesu. W rzeczywistości kolejne wywołania tego procesu niemal przychodzą „za darmo”.
Porównaj i porównaj następujące elementy:
MMAP () plik 1 GB. Twój VMSize będzie wynosił 1 + GB. Ale Twój Resident Set Size będzie tylko częściami pliku, w którym spowodowałeś utworzenie stronicowania (poprzez usunięcie odniesienia wskaźnika do tego regionu). A jeśli „przeczytasz” cały plik, to zanim dojdziesz do końca, jądro mogło już wygenerować strony początkowe (jest to łatwe, ponieważ jądro dokładnie wie, jak / gdzie zamienić te strony, jeśli ponownie się wyrejestrujesz) ). W obu przypadkach ani VMSize, ani RSS nie są dobrym wskaźnikiem „zużycia” pamięci. Tak naprawdę nic nie edytowałeś w malloc ().
Natomiast Malloc () i dotknij DUŻO pamięci - aż pamięć zostanie zamieniona na dysk. Zatem przydzielona pamięć przekracza teraz wartość RSS. Tutaj twój VMSize może zacząć ci coś mówić (twój proces ma więcej pamięci niż to, co faktycznie znajduje się w twojej pamięci RAM). Ale nadal trudno jest odróżnić maszynę wirtualną, która jest stronami udostępnionymi, i maszynę wirtualną, która zamienia dane.
To właśnie tutaj interesuje się valgrind / masyw. Pokazuje, co celowo przydzieliłeś (niezależnie od stanu twoich stron).
htop
autora na jedno podobne pytanie, które miałem poprzedniego dnia ... Jak obliczyć zużycie pamięci z / proc / meminfo (jak htop)