Почему мое ядро ​​Linux не может восстановить свою память памяти?

У меня есть система, которая страдала от постоянно увеличивающегося использования памяти, пока не достигла точки, когда она ударила по swap даже для обыденных вещей и, следовательно, стала довольно безразличной. Похоже, виновником было выделение памяти ядром, но мне трудно понять, что именно происходит в ядре.

Как я могу сказать, какие потоки / модули ядра / что-либо еще отвечают за определенные фрагменты использования памяти ядра?

Вот график использования памяти системой с течением времени:

Использование системной памяти;  slab_unrecl растет со временем

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, чтобы быть уверенным, что вы не подгоняете размеры. Попробуйте новые версии ядра или другой дистрибутив.

Другие вопросы по тегам