Odkryłem, że pidstat
byłoby to dobre narzędzie do monitorowania procesów. Chcę obliczyć średnie zużycie pamięci dla określonego procesu. Oto kilka przykładowych danych wyjściowych:
02:34:36 PM PID minflt/s majflt/s VSZ RSS %MEM Command
02:34:37 PM 7276 2.00 0.00 349212 210176 7.14 scalpel
(Jest to część wyniku z pidstat -r -p 7276
.)
Czy powinienem użyć informacji o rozmiarze zestawu rezydentnego (RSS) lub rozmiarze wirtualnym (VSZ) do obliczenia średniego zużycia pamięci? Przeczytałem kilka rzeczy na Wikipedii i na forach, ale nie jestem pewien, czy w pełni rozumiem różnice. Ponadto wydaje się, że żaden z nich nie jest niezawodny. Jak więc mogę monitorować proces, aby uzyskać zużycie pamięci?
Przydałaby się wszelka pomoc w tej sprawie.
Odpowiedzi:
RSS to ilość pamięci, jaką proces ten ma obecnie w pamięci głównej (RAM). VSZ to, ile pamięci wirtualnej ma cały proces. Obejmuje to wszystkie rodzaje pamięci, zarówno w pamięci RAM, jak i zamienione. Liczby te mogą zostać zniekształcone, ponieważ obejmują również biblioteki współdzielone i inne typy pamięci. Możesz mieć pięćset wystąpień
bash
, a całkowity rozmiar ich pamięci nie będzie sumą ich wartości RSS lub VSZ.Jeśli chcesz uzyskać bardziej szczegółowe pojęcie na temat śladu pamięci procesu, masz kilka opcji. Możesz przejść
/proc/$PID/map
i odrzucić rzeczy, których nie lubisz. Jeśli są to biblioteki współdzielone, obliczenia mogą się skomplikować w zależności od potrzeb (które, jak sądzę, pamiętam).Jeśli zależy Ci tylko na wielkości sterty procesu, zawsze możesz po prostu przeanalizować
[heap]
wpis wmap
pliku. Rozmiar przydzielony przez jądro dla sterty procesów może, ale nie musi, odzwierciedlać dokładną liczbę bajtów, o które proces poprosił o przydzielenie. Są drobne szczegóły, wewnętrzne elementy jądra i optymalizacje, które mogą to zrzucić. W idealnym świecie będzie to tyle, ile potrzebuje Twój proces, zaokrąglone w górę do najbliższej wielokrotności rozmiaru strony systemowej (getconf PAGESIZE
powie ci, co to jest - na komputerach PC to prawdopodobnie 4096 bajtów).Jeśli chcesz zobaczyć, ile pamięci przydzielił proces , jednym z najlepszych sposobów jest rezygnacja z pomiarów po stronie jądra. Zamiast tego instrumentu sterty pamięć C biblioteki (de) funkcjonuje alokacji z
LD_PRELOAD
mechanizmu. Osobiście lekko nadużywam,valgrind
aby uzyskać informacje na temat tego rodzaju rzeczy. (Należy pamiętać, że zastosowanie oprzyrządowania będzie wymagało ponownego uruchomienia procesu).Uwaga: ponieważ możesz być również środowiskiem testowym,
valgrind
spowoduje to, że twoje programy będą nieco wolniejsze (ale prawdopodobnie w granicach tolerancji).źródło
/proc/$PID/maps
jest to różnica w literówce lub dystrybucji?Minimalny możliwy do uruchomienia przykład
Aby to miało sens, musisz zrozumieć podstawy stronicowania: https://stackoverflow.com/questions/18431261/how-does-x86-paging-work, aw szczególności, że system operacyjny może przydzielić pamięć wirtualną za pomocą tabel stron / prowadzenie wewnętrznej księgi pamięci (pamięć wirtualna VSZ), zanim faktycznie będzie miała pamięć zapasową na RAM lub dysku (pamięć rezydentna RSS).
Teraz, aby to zaobserwować w akcji, stwórzmy program, który:
mmap
main.c
GitHub w górę .
Skompiluj i uruchom:
gdzie:
echo 1 | sudo tee /proc/sys/vm/overcommit_memory
: wymagany dla Linuksa, abyśmy mogli wykonać połączenie mmap większe niż fizyczna pamięć RAM: https://stackoverflow.com/questions/2798330/maximum-memory-which-malloc-can-allocate/57687432#57687432Wyjście programu:
Status wyjścia:
co według reguły liczby 128 + oznacza, że otrzymaliśmy numer sygnału
9
, któryman 7 signal
mówi , że to SIGKILL , który jest wysyłany przez zabójcę braku pamięci w systemie Linux .Interpretacja wyjściowa:
printf '0x%X\n' 0x40009A4 KiB ~= 64GiB
(ps
wartości w KiB) po mmap.extra_memory_committed 0
, co oznacza, że jeszcze nie dotknęliśmy żadnych stron. RSS to mały plik1648 KiB
przeznaczony do normalnego uruchamiania programu, takiego jak obszar tekstowy, globały itp.8388608 KiB == 8GiB
wartości stron. W rezultacie RSS wzrosła dokładnie o 8 GIB do8390256 KiB == 8388608 KiB + 1648 KiB
Zobacz także: Potrzebujesz wyjaśnienia na temat rozmiaru zestawu rezydentnego / rozmiaru wirtualnego
Dzienniki zabójców OOM
Nasze
dmesg
polecenia pokazały dzienniki zabójców OOM.Dokładna ich interpretacja została zapytana na:
Pierwszą linią dziennika było:
Widzimy więc, co ciekawe, że to demon MongoDB zawsze działa w moim laptopie w tle, który jako pierwszy wyzwalał zabójcę OOM, prawdopodobnie gdy biedak próbował przydzielić trochę pamięci.
Jednak zabójca OOM niekoniecznie zabija tego, który go obudził.
Po wywołaniu jądro drukuje tabelę lub procesy, w tym
oom_score
:a dalej widzimy, że nasze własne małe
main.out
tak naprawdę zginęło przy poprzednim wywołaniu:Dziennik ten wspomina,
score 865
który proces miał, prawdopodobnie najwyższy (najgorszy) wynik zabójcy OOM, jak wspomniano w: Jak zabójca OOM decyduje, który proces zabić jako pierwszy?Co ciekawe, wszystko najwyraźniej wydarzyło się tak szybko, że zanim uwolniona pamięć została rozliczona, proces
oom
został ponownie obudzonyDeadlineMonitor
:i tym razem zabił proces Chromium, który zwykle jest normalnym zapisem pamięci mojego komputera:
Testowany w Ubuntu 19.04, jądro Linuksa 5.0.0.
źródło