Відстеження "відсутнього" використання пам'яті в Linux


10

На ядрі Arch 3.6.7 x86_64 я намагаюся врахувати використання пам'яті системи, і чим більше я дивлюся на неї, тим більше виявляється дірка (у бухгалтерському обліку використовуваної пам’яті не має місце отвір використання).

Це свіжозавантажена система. Маючи не багато іншого, крім systemd та sshd, щоб зробити це просто

$ 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

Найбільш детальна інформація про пам'ять, яку я можу знайти, - це з 2007 року, яка, як видається, призвела до додавання поля Pss до загального обліку ядра для процесу, але їх код python призначений для старих ядер і, на жаль, деяких файлів / proc / k * з того часу зникли. The / proc / meminfo також корисна, але також трохи старіє.

Отже, демонстрація того, що я бачу.

# 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

Якщо ми додамо використане:

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

Усі активні * / неактивні *, здається, лічильники, застосовані на деяких сторінках (не на всіх), тому можуть дублювати те, що рахується в інших місцях.

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

Тут, здається, Commited_AS уважно відстежує суму приватної / спільної пам’яті користувальницької дисконтування спільних файлів з / proc / * / smaps. врахування PSS також складається з рядків. (З інтересу я отримую набагато набагато більший Commited_AS на 32-бітовій дебіані 2.6.32-5-686)

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

Плита знаходиться в рядку з / proc / slabinfo

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

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

Так ~ 63М короткий. Мене вражає, що ядра та всіх завантажених модулів бракує деяких МБ. Плита, здається, покриває багато, тому, якщо є якісь відсутні, я не впевнений, чи це було б дорівнює ~ 60Mb?

63 якось близький до фігури Active + Inactive, але це не вірно.

Так хтось знає магічну формулу ?? Інакше, якщо цифра, на яку я дивлюсь, - це правильні, які сірі ділянки в розподілі пам’яті, про які я можу опинитися?

Здається, Linux з'їв мого барана! Хоча менша частина, ніж зазвичай звинувачують =)

редагувати Commited_AS - це здогадка з ядра, скільки пам'яті йому потрібно, щоб покрити 99,9% того, що вона зробила, тому не є реальним виділеним числом. AnonPages + Mapped є його складовою, так що зараз залишається більший отвір, приблизно 100 Мб.

User + Kernel
28368 + 32144 = 60512 != 157036

AnonPages та Mapped в основному відстежують інформацію про anon / відображену на карті з / proc / [0-9] * / smaps wgen з урахуванням PSS / Shared.

Зарезервовані області, здається, всі вписуються в шматок, знятий із загальної пам'яті:

Загальна freeпам'ять - 16345032Kb
Загальна системна пам'ять - 16777216Kb
PCI 'отвір' - lspci -v 266520K = 16510696K
Зарезервовано біос - dmesg 92793K = 16417903K

edit2 Я помітив, що додаткового використання пам’яті не було в VM, що працює в оригінальній коробці, з якої /proc/meminfoбуло. Тож я почав роздумувати, побачивши, що між ними відрізняється. Врешті-решт виявлено, що збільшення загальної доступної фізичної пам'яті співпало із збільшенням використовуваної пам'яті.

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

Це виходить, щоб ~ 8 Мб виділялося на кожні 1 ГБ пам'яті. Можливо, це карта пам'яті в ядрі ... але я думав, що вона буде рости лише в міру виділення пам'яті, а не установки при завантаженні.

Було б цікаво подивитися, чи має хто-небудь доступ до будь-яких машин bigmem, якщо тенденція продовжиться?


psбрехня за задумом. Не використовуйте його для обліку пам'яті.
bahamat

2
ура, але це не підходить ps. Це загальне використання в Росії /proc/meminfo. Єдиний облік процесу здійснювався за допомогою smaps, який враховує спільну та приватну пам'ять, але це було лише для порівняння зі значеннями AnonPages / Mapped з meminfo.
Метт


звідси посилання в моєму дописі про Linux насправді їсть мій баран =)
Метт

Відповіді:


3

"Пам'ять, яка використовується процесом" є немаєчітка концепція вирішення в сучасних операційних системах. Що можна виміряти - це розмір адресного простору процесу (SIZE) та розмір встановленого резидента (RSS, скільки сторінок у адресному просторі зараз знаходиться в пам'яті). Частина RSS поділяється (більшість процесів у пам’яті поділяють одну копію glibc, і так для різних інших бібліотек, що працюють у спільному виконанні; кілька процесів, що працюють з тим самим виконуваним файлом, поділяються нею, процеси розщеплюють обмін даними, доступними лише для читання, і, можливо, шматок ще не модифікованих читати-записувати дані з батьком). З іншого боку, пам'ять, яка використовується для процесу ядром, не враховується, як таблиці сторінок, буфери ядра та стек ядра. У загальній картині ви повинні враховувати пам'ять, зарезервовану для відеокарти, використання ядра та різні "дірки", зарезервовані для DOS та інших доісторичних систем (це не так багато,

Єдиний спосіб отримати загальну картину - це те, що ядро ​​звітує як таке. Додавання чисел з невідомими перекриттями та невідомими залишеними аутами - це приємна вправа з арифметики, не більше того.


1
"Пам'ять на процес" не чітко вирізана, але я не можу зрозуміти, чому це має вплинути на відстеження загального використання? Для ядра загальні PageTables, slab, KernelStack та інші непроцесорні лічильники пам’яті повідомляються в / proc / meminfo та включаються до того, що я намагаюся врахувати (схоже, пам’ятка процесу також є). На додаток до загальних лічильників я розглядав фрагменти карти для anon / mapped, спільної / приватної пам’яті, щоб отримати уявлення про те, де може обліковуватися пам'ять процесу в / proc / meminfo. Я націлений на те, який набір чисел VM додається до фізичного, в якому я явно маю дірку.
Метт

1
В основному psне в змозі правильно обліку пам'яті. Тому не використовуйте його. Які psзвіти були б істинними, лише якщо цей процес був би єдиним запущеним у системі (неможливість). Більше про те, чому ви цього не робите, psчитайте тут: Розуміння використання пам'яті в Linux
bahamat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.