Pomiar zużycia pamięci RAM przez program

46

time to genialne polecenie, jeśli chcesz dowiedzieć się, ile czasu zajmuje procesor.

Szukam czegoś podobnego, co może zmierzyć maksymalne użycie pamięci RAM programu i wszystkich dzieci. Najlepiej, aby odróżniał przydzieloną pamięć, która była używana i nieużywana. Być może może to nawet dać medianę użycia pamięci (więc użycia pamięci należy się spodziewać podczas długotrwałego działania).

Więc chciałbym zrobić:

rammeassure my_program my_args

i uzyskaj dane wyjściowe podobne do:

Max memory allocated: 10233303 Bytes
Max memory used: 7233303 Bytes
Median memory allocation: 5233303 Bytes

Patrzyłem na memusg https://gist.github.com/526585/590293d6527c91e48fcb08edb8de9fd6c88a6d82, ale uważam to za nieco włamanie.

Ole Tange
źródło

Odpowiedzi:

24

Za pomocą narzędzia tstime można zmierzyć zużycie dużej ilości pamięci (RSS i wirtualnej) procesu.

Na przykład:

$ tstime date       
Tue Aug 16 21:35:02 CEST 2011

Exit status: 0

pid: 31169 (date) started: Tue Aug 16 21:35:02 2011
        real   0.017 s, user   0.000 s, sys   0.000s
        rss      888 kb, vm     9764 kb

Obsługuje również łatwiejszy do analizy tryb wyjściowy ( -t).

maxschlepzig
źródło
Lubię to. Zrobił nawet The Right Thing z./tstime -t bash -c 'perl -e "\$a=\"x\"x100000000;\$b=\$a.\$a;\$b=\"\";\$a=\"\";sleep 10;"'
Ole Tange
3
„Wykorzystanie pamięci RAM przez proces” nie jest dobrze zdefiniowaną wartością: jeśli działa kilka instancji tego samego programu, współużytkują one plik wykonywalny. Większość programów współdzieli glibc(i inne różne biblioteki, dla niektórych nazywane są „współdzielonymi”). Wiele demonów ładuje konfigurację do pamięci i dzieci podnośnika (2), które następnie współużytkują dane konfiguracji. Następnie są dane w buforach readahead / writebehind zarządzanych przez jądro. A potem są usługi, które są stadem luźno powiązanych procesów (pomyśl o środowisku pulpitu i wszystkich jego apletach i innych elementach).
vonbrand
@vonbrand, jak jądro Linuksa oblicza wartości RSS / VSS, jest dobrze zdefiniowane.
maxschlepzig
@maxschlepzig, może również obliczyć losowe wartości, co nie znaczy, że mają na myśli to, co myślisz, że mają na myśli: Zestaw rezydentny to tylko strony w przestrzeni adresowej procesu, które są obecnie w pamięci. To nie jest „pamięć używana przez ten proces”, obejmuje to, co udostępnia.
vonbrand
@vonbrand Większość przypadków użycia pomiaru pamięci procesowej będzie chciała zmierzyć niepodzielone anonimowe strony, które powinny być bardzo przewidywalne przy tych samych danych wejściowych.
Vladimir Panteleev
28

timejest wbudowany w twoją powłokę. Jeśli chcesz, timeale potrzebujesz więcej informacji, wypróbuj GNU timew -vtrybie verbose ( ):

/usr/bin/time -v sleep 5               
    Command being timed: "sleep 5"
    User time (seconds): 0.00
    System time (seconds): 0.00
    Percent of CPU this job got: 0%
    Elapsed (wall clock) time (h:mm:ss or m:ss): 0:05.00
    Average shared text size (kbytes): 0
    Average unshared data size (kbytes): 0
    Average stack size (kbytes): 0
    Average total size (kbytes): 0
    Maximum resident set size (kbytes): 2144
    Average resident set size (kbytes): 0
    Major (requiring I/O) page faults: 0
    Minor (reclaiming a frame) page faults: 179
    Voluntary context switches: 2
    Involuntary context switches: 1
    Swaps: 0
    File system inputs: 0
    File system outputs: 0
    Socket messages sent: 0
    Socket messages received: 0
    Signals delivered: 0
    Page size (bytes): 4096
    Exit status: 0

Wyszukaj w menedżerze pakietów „czas” lub „gnutime”.

Rufo El Magufo
źródło
3
Zauważ, że niektóre informacje zgłaszane według czasu GNU mogą być niedokładne. Np. Pod Ubuntu 10.04: Strona podręcznika mówi „Liczby są tak dobre, jak te zwrócone przez wait3 (2)”. Tj. wait3Wypełnia strukturę opisaną w getrusage(2): „Nie wszystkie pola mają znaczenie w Linuksie. [..] ”.
maxschlepzig
4
Na przykład w programie testowym, który dokładnie przydziela 10 MB (i dotyka każdej strony) - czas GNU zgłasza maxRSS 42608 KiB - i tstimeraportuje 10652 KiB. Ponownie pod Ubuntu 10.04.
maxschlepzig
Chciałbym, gdyby to było takie proste. Na moim komputerze Ubuntu Próbowałem: /usr/bin/time -v perl -e '$a="x"x100000000;$b=$a.$a;sleep 10;'. góra mówi, że zajmuje to około 570 MB, ale czas mówi 2,3 GB. W praktyce liczba ta nie jest dla mnie możliwa.
Ole Tange
Współczynnik 4 jest ustalony w czasie GNU 1.7 i dlatego działa zgodnie z oczekiwaniami.
Ole Tange
Ważna uwaga: „Maksymalny rozmiar zestawu rezydenta” działa tylko od Linuksa 2.6.32.
Jan Hudec
17

Może przesada, ale właśnie znalazłem valgrindfajne narzędzie o nazwie massif. Testowałem na xterm:

valgrind --trace-children=yes --tool=massif xterm
ms_print massif.out.* | less

Otrzymujesz ładny wykres wykorzystania pamięci:

    MB
4.230^                     #                    :::::::  :::      @@:     ::: 
     |   @                 #:::@::@@:::::@::::::: :: : ::: :::::::@ ::::::: ::
     |   @               ::#:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::::@@:::::::::: #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
     |   @::: @ :: ::: : : #:: @: @ ::: :@: :: :: :: : ::: ::: : :@ :: : :: ::
   0 +----------------------------------------------------------------------->Mi
     0                                                                   292.4

wraz ze zbyt szczegółowymi informacjami o zużyciu pamięci. Szczegóły w instrukcji Valgrind .

Programy będą działać około 20 razy wolniej. Uruchomiłem też kilka poleceń wewnątrz xterm. Ich pamięć została uwzględniona, ponieważ --trace-children=yesistnieje taka opcja!

Stéphane Gimenez
źródło
1
Kara 20x prędkości sprawia, że ​​jest to niewystarczające w mojej sytuacji. W przeciwnym razie bardzo ładny wykres!
Ole Tange
1
Wygląda na to, że przynajmniej w wersji 3.8.1 valgrind, której używam, booleany są akceptowane tylko w formie „tak / nie”, a nie „prawda / fałsz”. Mój narzekał! :-)
MakisH
6

Chociaż temat jest dość stary, chcę udostępnić inny projekt, który powstał z funkcji jądra Linuksa cgroups.

https://github.com/gsauthof/cgmemtime :

cgmemtime mierzy zużycie wody w pamięci RSS + CACHE przez proces i jego procesy potomne.

Aby móc to zrobić, umieszcza proces we własnej grupie cg.

Na przykład proces A przydziela 10 MiB i uruchamia podrzędne dziecko B, które przydziela 20 MiB i które uruchamia podrzędne dziecko C, które przydziela 30 MiB. Wszystkie trzy procesy dzielą okno czasowe, w którym ich alokacja skutkuje odpowiednim użyciem pamięci RSS (rozmiar zestawu rezydentnego).

Pytanie brzmi: ile pamięci faktycznie jest używane w wyniku uruchomienia A?

Odpowiedź: 60 MiB

cgmemtime to narzędzie do odpowiedzi na takie pytania.

Vlad Frolov
źródło
3

Wygląda na to, że tstime już nie działa w systemie innym niż root w systemie Linux> = 3.0. Oto narzędzie do sondowania, które napisałem, aby włamać się do tego problemu: https://github.com/jhclark/memusg/blob/master/memusg

jhclark
źródło
/usr/bin/time -vdaje poprawne wyjście w nowszych wersjach. W starszych wersjach wystarczy podzielić przez 4, aby uzyskać prawidłową kwotę.
Ole Tange
Nie sądzę jednak, aby czas -v obsługiwał maksymalny rozmiar pamięci (tylko RSS). Czy ktoś może to potwierdzić w najnowszej wersji?
jhclark