Назад | Перейти на главную страницу

Почему MemAvailable намного меньше, чем MemFree + Buffers + Cached?

Я использую рабочую станцию ​​Linux без подкачки и установил earlyoom демон для автоматического завершения некоторых процессов, если у меня заканчивается оперативная память. В earlyoom работает путем мониторинга ядра MemAvailable значение, и если доступной памяти становится достаточно мало, это убивает менее важные процессы.

Это работало нормально долгое время, но внезапно я столкнулся с ситуацией, когда MemAvailable внезапно становится действительно низким по сравнению с остальной системой. Например:

$ grep -E '^(MemTotal|MemFree|MemAvailable|Buffers|Cached):' /proc/meminfo 
MemTotal:       32362500 kB
MemFree:         5983300 kB
MemAvailable:    2141000 kB
Buffers:          665208 kB
Cached:          4228632 kB

Обратите внимание на то, что MemAvailable намного ниже, чем MemFree+Buffers+Cached.

Могу ли я воспользоваться какими-либо инструментами, чтобы выяснить, почему это происходит? Я чувствую, что производительность системы немного хуже, чем обычно, и мне пришлось остановить earlyoom сервис, потому что его логика не будет работать, если MemAvailable является стабильным (то есть правильно описывает доступную память для процессов пользовательского режима).

В соответствии с https://superuser.com/a/980821/100154 MemAvailable - это оценка того, сколько памяти доступно для запуска новых приложений без подкачки. Что это означает, поскольку у меня нет свопа? Это должно означать объем памяти, который новый процесс может получить до запуска OOM Killer (потому что это логически приведет к ситуации «своп заполнен»)?

Я предполагал, что MemAvailable > = MemFree всегда будет правдой. Не здесь.

Дополнительная информация:

Поиск в Интернете предполагает, что причиной могут быть открытые файлы, которые не поддерживаются файловой системой и, как следствие, не могут быть освобождены из памяти. Команда sudo lsof | wc -l выходы 653100 поэтому я определенно не могу вручную просмотреть этот список.

Вершина sudo slabtop говорит

 Active / Total Objects (% used)    : 10323895 / 10898372 (94.7%)
 Active / Total Slabs (% used)      : 404046 / 404046 (100.0%)
 Active / Total Caches (% used)     : 104 / 136 (76.5%)
 Active / Total Size (% used)       : 6213407.66K / 6293208.07K (98.7%)
 Minimum / Average / Maximum Object : 0.01K / 0.58K / 23.88K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME                   
4593690 4593656  99%    1.06K 153123       30   4899936K ext4_inode_cache
3833235 3828157  99%    0.19K 182535       21    730140K dentry
860224 551785  64%    0.06K  13441       64     53764K kmalloc-64
515688 510872  99%    0.66K  21487       24    343792K proc_inode_cache
168140 123577  73%    0.20K   8407       20     33628K vm_area_struct
136832 108023  78%    0.06K   2138       64      8552K pid
...

что мне кажется нормальным.

Создание приблизительного резюме lsof

$ sudo lsof | awk '{ print $2 }' | sort | uniq -c | sort -h | tail
   6516 1118
   7194 2603
   7884 18727
   8673 19951
  25193 28026
  29637 31798
  38631 15482
  41067 3684
  46800 3626
  75744 17776

указывает мне PID 17776, который является экземпляром VirtualBox. (Другими процессами с большим количеством открытых файлов являются Chrome, Opera и Thunderbird.) Поэтому я не сильно удивлюсь, если позже выясню, что основной причиной этой проблемы является VirtualBox, потому что это единственное, что действительно мешает ядру.

Однако проблема не исчезнет, ​​даже если я выключу виртуальный бокс и убью Chrome, Opera и Thunderbird.

Как вы видели в статье, на которую вы ссылаетесь, весь набор вычислений вокруг MemAvailable построен на вычислении того, сколько памяти можно использовать, без каких-либо подкачки. Вы можете увидеть в фактический патч который реализовал число MemAvailable, которое MemAvailable = MemFree - LowWaterMark + (PageCache - min (PageCache / 2, LowWaterMark))

Эта формула указывает на вероятность того, что MemAvailable вашей системы низка, потому что ваша нижняя отметка - объем свободной памяти, который, по мнению вашей системы, необходим ей в качестве рабочего пространства, вероятно, очень высок. Это имеет смысл в среде без подкачки, где система гораздо больше озабочена нехваткой памяти. Вы можете посмотреть, какой у вас текущий низкий водяной знак:

 $ cat /proc/sys/vm/min_free_kbytes

Подозреваю, что в вашем случае это довольно много.

Почти все эвристические методы управления памятью Linux предполагают, что вы будете работать с некоторым пространством подкачки.

Могу ли я воспользоваться какими-либо инструментами, чтобы выяснить, почему это происходит?

Несоответствие может быть вызвано неправильным расчетом. Ответ, на который вы ссылаетесь, не выделяет этого, но посмотрите на связанное сообщение фиксации:

[Люди] обычно делают это, складывая «бесплатно» и «кэшировано», что было нормально десять лет назад, но почти наверняка ошибается сегодня. Это неправильно, потому что Cached включает память, которая не может быть освобождена в качестве кэша страниц, например сегменты разделяемой памяти, tmpfs и ramfs.

Часть Cached который не может быть освобожден как кеш страницы (вздох), считается как Shmem в /proc/meminfo.

Вы также можете запустить free, и посмотрите в столбец «общий».

Часто это вызвано установленным tmpfs. Проверьте df -h -t tmpfs.