Почему мое ядро Linux не может восстановить свою память памяти?
У меня есть система, которая страдала от постоянно увеличивающегося использования памяти, пока не достигла точки, когда она ударила по swap даже для обыденных вещей и, следовательно, стала довольно безразличной. Похоже, виновником было выделение памяти ядром, но мне трудно понять, что именно происходит в ядре.
Как я могу сказать, какие потоки / модули ядра / что-либо еще отвечают за определенные фрагменты использования памяти ядра?
Вот график использования памяти системой с течением времени:
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
Выводы:
- Распределитель slab ядра использует около 2,3 ГБ ОЗУ
- Почти все это невозможно исправить
- Около 1,3 ГБ занято
kmem_cache
кэш - Еще 0,5 ГБ принадлежит кэшам kmalloc различного размера
Это где я врезался в стену. Я не выяснил, как заглянуть в эти кэши и понять, почему они стали такими большими (или почему их память не востребована). Как я могу пойти дальше в моих исследованиях?
1 ответ
perf kmem record --slab
будет собирать данные профилирования и perf kmem stat --slab --caller
будет промежуточный итог по символу ядра.
Однако это не объясняет, почему ваша рабочая нагрузка делает это. Добавить в perf record
и посмотрите на отчет, чтобы увидеть, что вызывает ядро.
kprobes может отслеживать определенные стеки ядра, что приводит к типу выделения. Я сам не очень знаком с этим, но попробуйте прочитать примеры, сопровождающие сценарии eBPF, такие как slabratetop.
Также немного измените вещи на вашем хосте. Добавьте RAM, чтобы быть уверенным, что вы не подгоняете размеры. Попробуйте новые версии ядра или другой дистрибутив.