Śledzenie „brakującego” zużycia pamięci w systemie Linux


10

W jądrze Arch 3.6.7 x86_64 próbuję uwzględnić zużycie pamięci przez system, im więcej na niego patrzę, tym bardziej wydaje się, że jest dziura (w rozliczeniu używanej pamięci nie jest dziura w użycie).

To jest świeżo uruchomiony system. Nie ma wiele uruchomionych programów oprócz systemd i sshd, aby było to proste

$ ps aux | sort -n -k6
...
root       316  0.0  0.0   7884   812 tty1     Ss+  14:37   0:00 /sbin/agetty --noclear tty1 38400
matt       682  0.0  0.0  24528   820 pts/0    S+   15:09   0:00 sort -n -k6
dbus       309  0.0  0.0  17280  1284 ?        Ss   14:37   0:00 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
matt       681  0.0  0.0  10808  1364 pts/0    R+   15:09   0:00 ps aux
root       308  0.0  0.0  26060  1516 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-logind
root       148  0.0  0.0  25972  1692 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-udevd
matt       451  0.0  0.0  78180  2008 ?        S    14:37   0:00 sshd: matt@pts/0
root       288  0.0  0.0  39612  2708 ?        Ss   14:37   0:00 /usr/sbin/sshd -D
matt       452  0.0  0.0  16452  3248 pts/0    Ss   14:37   0:00 -bash
root         1  0.0  0.0  32572  3268 ?        Ss   14:37   0:00 /sbin/init
root       299  0.0  0.0  69352  3604 ?        Ss   14:37   0:00 /usr/sbin/syslog-ng -F
root       449  0.0  0.0  78040  3800 ?        Ss   14:37   0:00 sshd: matt [priv]
root       161  0.0  0.0 358384  9656 ?        Ss   14:37   0:00 /usr/lib/systemd/systemd-journald

Najbardziej szczegółowe informacje pamięci mogę znaleźć jest to od 2007 roku, która wydaje się zaowocowały dodaniem dziedzinie PSS do jądra rachunkowości ogólnej dla procesu, ale ich kod Python jest dla starszych jąder i niestety niektóre z / proc / K * plikach zniknęły od tego czasu. Dokumentacja / proc / meminfo jest również pomocna, ale także trochę się starzeje.

Tak więc demonstracja tego, co widzę.

# cat /proc/meminfo
MemTotal:       16345780 kB
MemFree:        16129940 kB
Buffers:           10360 kB
Cached:            48444 kB
SwapCached:            0 kB
Active:            24108 kB
Inactive:          46724 kB
Active(anon):      12104 kB
Inactive(anon):     3616 kB
Active(file):      12004 kB
Inactive(file):    43108 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         11996 kB
Mapped:            16372 kB
Shmem:              3696 kB
Slab:              25092 kB
SReclaimable:      11716 kB
SUnreclaim:        13376 kB
KernelStack:         928 kB
PageTables:         2428 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     8172888 kB
Committed_AS:      34304 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      372788 kB
VmallocChunk:   34359362043 kB
HardwareCorrupted:     0 kB
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       12288 kB
DirectMap2M:    16680960 kB

Jeśli dodamy używane:

MemTotal - MemFree - Buffers - Cached = Used
16345780 - 16129940 - 10360 - 48444 = 157036

Wszystkie aktywne * / nieaktywne * wydają się być licznikami stosowanymi na niektórych stronach (nie na wszystkich), więc mogą powielać to, co jest policzone gdzie indziej.

Active + Inactive = Used
46724  + 24108    = 70832 (not quite)

Commited_AS tutaj wydaje się ściśle śledzić sumę przestrzeni prywatnej / pamięci dzielonej przestrzeni użytkownika pomijając udostępnione pliki z / proc / * / smaps. biorąc pod uwagę PSS również szereguje. (Z zainteresowania otrzymuję znacznie, znacznie większy Commited_AS na 32-bitowym debianie 2.6.32-5-686)

AnonPages + Mapped + Commited_AS = Userspace?
11996     + 16372  + 34304       = 62672

Płyta jest wbudowana w / proc / slabinfo

Slab +  Shmem + KernelStack + PageTables = Kernelspace?
25092 + 3696  + 928         + 2428       = 32144

Userspace? + Kernelspace? = Used?
62672      + 32144        = 94816

Tak więc ~ 63 mln. Uderza mnie, że w jądrze i wszystkich załadowanych modułach brakuje niektórych MB. Płyta wydaje się jednak pokrywać bardzo dużo, więc jeśli czegoś brakuje, nie jestem pewien, czy równałoby się to ~ 60 Mb?

63 jest trochę bliżej liczby Aktywna + Nieaktywna, ale to nie wydaje się właściwe.

Czy ktoś zna magiczną formułę? W przeciwnym razie, jeśli figura, na którą patrzę, jest odpowiednia, jakie są szare obszary w alokacji pamięci, w których mogę się zagłuszyć?

Wygląda na to, że linux zjadł mojego barana! Chociaż mniejsza niż zwykle porcja =)

edytuj Commited_AS to oszacowanie z jądra, ile pamięci potrzebowałoby na pokrycie 99,9% tego, co popełnił, więc nie jest to prawdziwie przydzielona liczba. AnonPages + Mapped jest jego składnikiem, dzięki czemu pozostawia większy otwór, około 100 MB.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages i Mapped przeważnie śledzą z anon / mapowanymi informacjami z / proc / [0-9] * / smaps wgen biorąc pod uwagę PSS / Shared.

Zarezerwowane obszary wydają się pasować do części zdjętej z całkowitej pamięci:

Całkowita freepamięć wynosi 16345032 KB
Całkowita pamięć systemu to 16777216 KB
„dziura” PCI - lspci -v266520 K = 16510696 K
Bios Zarezerwowane - dmesg 92793 K = 16417903 K

edit2 Zauważyłem, że to dodatkowe użycie pamięci nie działało na maszynie wirtualnej działającej w oryginalnym polu, z /proc/meminfoktórego pochodziła. Zacząłem więc szukać czegoś, co różniło się między nimi. W końcu stwierdzono, że wzrost całkowitej dostępnej pamięci fizycznej zbiegł się ze wzrostem używanej pamięci.

phys 16GB used>144508     vm>50692      user>21500      kern>26428      u+ktot>47928
vm   64MB used>24612      vm>31140      user>14956      kern>14440      u+ktot>29396
vm  256MB used>26316      vm>35260      user>14752      kern>14780      u+ktot>29532
vm    1GB used>33644      vm>35224      user>14936      kern>14772      u+ktot>29708
vm    2GB used>41592      vm>35048      user>14736      kern>15056      u+ktot>29792
vm    4GB used>57820      vm>35232      user>14780      kern>14952      u+ktot>29732
vm    8GB used>82932      vm>36912      user>15700      kern>15388      u+ktot>31088
vm   12GB used>110072     vm>35248      user>14812      kern>15624      u+ktot>30436
vm   15GB used>122012     vm>35424      user>14832      kern>15824      u+ktot>30656

To daje około 8 MB przydzielone na każdy 1 GB pamięci. Może to być mapa pamięci w jądrze ... ale pomyślałem, że powiększy się tylko w miarę przydzielania pamięci, a nie konfiguracji podczas rozruchu.

Byłoby ciekawie sprawdzić, czy ktokolwiek ma dostęp do maszyn bigmem, jeśli trend się utrzyma?


psleży z założenia. Nie używaj go do rozliczania pamięci.
bahamat

2
wiwaty, ale to nie liczy się ps. To ogólne użycie w /proc/meminfo. Jedyne rozliczanie procesów odbywa się za pomocą smapów, które uwzględniają pamięć współdzieloną i prywatną, ale miało to jedynie na celu porównanie z wartościami AnonPages / Mapped z meminfo.
Matt


stąd odniesienie w moim poście na temat linux faktycznie zjadającego mojego barana =)
Mat.

Odpowiedzi:


3

„Pamięć używana przez proces” nie jestprzejrzysta koncepcja w nowoczesnych systemach operacyjnych. Można zmierzyć wielkość przestrzeni adresowej procesu (SIZE) i rozmiar zestawu rezydentnego (RSS, ile stron w przestrzeni adresowej jest obecnie w pamięci). Część RSS jest współdzielona (większość procesów w pamięci współdzieli jedną kopię glibc, a więc w przypadku innych bibliotek współdzielonych; kilka procesów uruchomionych w tym samym pliku wykonywalnym udostępnia ją, przetwarza rozwidlone dane tylko do odczytu i ewentualnie część niezmodyfikowanych jeszcze odczyt i zapis danych z rodzicem). Z drugiej strony, pamięć używana przez proces przez jądro nie jest uwzględniana, podobnie jak tabele stron, bufory jądra i stos jądra. W ogólnym obrazie musisz uwzględnić pamięć zarezerwowaną dla karty graficznej, użycie jądra i różne „dziury” zarezerwowane dla DOS i innych prehistorycznych systemów (to niewiele,

Jedynym sposobem na uzyskanie ogólnego obrazu jest to, co jądro zgłasza jako takie. Sumowanie liczb z nieznanymi nakładkami i nieznanymi pominięciami jest przyjemnym ćwiczeniem arytmetycznym, niczym więcej.


1
„pamięć na proces” nie jest jednoznaczna, ale nie rozumiem, dlaczego powinno to wpłynąć na ogólne wykorzystanie śledzenia? W przypadku jądra ogólne liczniki PageTables, Slab, KernelStack i inne nieprocesowe liczniki memów są zgłaszane w / proc / meminfo i uwzględniane w tym, co próbuję wyjaśnić (wydaje się, że mem procesowy też tam jest). Oprócz ogólnych liczników, na które patrzyłem dla poszczególnych map procesów dla pamięci anon / mapowanej, współużytkowanej / prywatnej, aby dowiedzieć się, gdzie pamięć procesu może być rozliczona w / proc / meminfo. Dążę do tego, jaki zestaw liczb maszyn wirtualnych stanowi element fizyczny, w którym mam wyraźną dziurę.
Mat.

1
Zasadniczo psjest niezdolny do prawidłowego rozliczenia pamięci. Więc nie używaj tego. Jakie psraporty byłyby prawdziwe, gdyby ten proces był jedynym uruchomionym w systemie (niemożliwość). Aby dowiedzieć się więcej o tym, dlaczego tego nie robisz, psprzeczytaj tutaj: Zrozumienie wykorzystania pamięci w systemie Linux
bahamat
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.