У меня есть система, которая страдала от постоянно увеличивающегося использования памяти, пока не достигла точки, когда она запускала подкачку даже для повседневных вещей и, следовательно, перестала отвечать. Похоже, что виновата была память, выделенная ядром, но мне трудно понять, что именно происходит в ядре.
Как я могу узнать, какие потоки / модули ядра / что-то еще отвечают за определенные фрагменты использования памяти ядра?
Вот график использования памяти системой с течением времени:
В slab_unrecl
растущее со временем значение соответствует SUnreclaim
поле в /proc/meminfo
.
Когда я бежал slabtop
ближе к концу этого графика и отсортировал его по размеру кеша, вот что он мне показал:
Active / Total Objects (% used) : 15451251 / 15530002 (99.5%)
Active / Total Slabs (% used) : 399651 / 399651 (100.0%)
Active / Total Caches (% used) : 85 / 113 (75.2%)
Active / Total Size (% used) : 2394126.21K / 2416458.60K (99.1%)
Minimum / Average / Maximum Object : 0.01K / 0.16K / 18.62K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
3646503 3646503 100% 0.38K 173643 21 1389144K kmem_cache
3852288 3851906 99% 0.06K 60192 64 240768K kmalloc-64
3646656 3646656 100% 0.06K 56979 64 227916K kmem_cache_node
1441760 1441675 99% 0.12K 45055 32 180220K kmalloc-128
499136 494535 99% 0.25K 15598 32 124784K kmalloc-256
1066842 1066632 99% 0.09K 25401 42 101604K kmalloc-96
101430 101192 99% 0.19K 4830 21 19320K kmalloc-192
19168 17621 91% 1.00K 599 32 19168K kmalloc-1024
8386 7470 89% 2.00K 525 16 16800K kmalloc-2048
15000 9815 65% 1.05K 500 30 16000K ext4_inode_cache
66024 45955 69% 0.19K 3144 21 12576K dentry
369536 369536 100% 0.03K 2887 128 11548K kmalloc-32
18441 16586 89% 0.58K 683 27 10928K inode_cache
44331 42665 96% 0.19K 2111 21 8444K cred_jar
12208 7529 61% 0.57K 436 28 6976K radix_tree_node
627 580 92% 9.12K 209 3 6688K task_struct
6720 6328 94% 0.65K 280 24 4480K proc_inode_cache
36006 36006 100% 0.12K 1059 34 4236K kernfs_node_cache
266752 266752 100% 0.02K 1042 256 4168K kmalloc-16
134640 133960 99% 0.02K 792 170 3168K fsnotify_mark_connector
1568 1461 93% 2.00K 98 16 3136K mm_struct
1245 1165 93% 2.06K 83 15 2656K sighand_cache
Выводы:
kmem_cache
тайникЗдесь я наткнулся на стену. Я не понял, как заглянуть внутрь этих кешей и понять, почему они стали такими большими (или почему их память не подлежит возврату). Как я могу продолжить свои расследования?
perf kmem record --slab
будет собирать данные профилирования и perf kmem stat --slab --caller
будет подытог по символу ядра.
Однако это не объясняет, почему ваша рабочая нагрузка делает это. Добавить в perf record
и просмотрите отчет, чтобы узнать, что вызывает ядро.
kprobes может отслеживать определенные стеки ядра, ведущие к определенному типу распределения. Я сам не очень знаком с этим, но попробуйте прочитать примеры, сопровождающие скрипты eBPF, такие как slabratetop.
Также немного измените вещи на вашем хосте. Добавьте оперативную память, чтобы убедиться, что вы не занижаете ее размер. Попробуйте более новые версии ядра или другой дистрибутив.