Я использую рабочую станцию 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
.