
Похоже, у меня утечка памяти в пространстве ядра, slab показывает, что kmalloc-4096 постоянно увеличивает ровный клип, пока не монополизирует все ресурсы оперативной памяти в системе и не вынудит выполнить подкачку.
Free показывает большую часть этого использования памяти как кэш, но отказывается освобождаться по необходимости или даже когда помечено как очищаемое вручную. Пример того, что мы видим:
$ sudo su -c "free -h && sync && echo 3 > /proc/sys/vm/drop_caches && free -h"
total used free shared buff/cache available
Mem: 15G 4.4G 166M 280M 10G 104M
Swap: 15G 7.8G 8.1G
total used free shared buff/cache available
Mem: 15G 4.4G 186M 280M 10G 115M
Swap: 15G 7.8G 8.1G
Стоит ли мне профилировать kmalloc, чтобы определить, где утечка? Если да, то как это сделать?
Это стандартная установка Ubuntu 16.04 на Intel i5 Skylake.
$ uname -a
Linux fire 4.4.0-78-generic #99-Ubuntu SMP Thu Apr 27 15:29:09 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
решение1
«Sync» не уменьшит бафф/кэш, он просто запрашивает, чтобы данные перешли на блочные устройства. Суть кэша в том, что данные остаются в кэшах RAM. Отправка 3 в drop_caches также не ждет, пока кэши будут удалены. Не могли бы вы добавить «sleep 60» перед «free»? Это может дать некоторое время для очистки памяти перед отчетом о free.
Если оставить «watch -n60 cat /proc/meminfo», можно увидеть область памяти, которая растет, но утечками являются не только кэш и буфер. Потребляя память, они выполняют свою задачу и максимально эффективно используют доступные ресурсы вашей системы.
Если процесс выгружен на диск, это не означает автоматически, что произошло что-то плохое. Ядро делает правильно, если этот процесс не использует все свои страницы и переходит в режим ожидания, есть разумная вероятность того, что на веб-сервере содержимое в корне www понадобится до того, как копия mutt останется запущенной на экране GNU, когда пользователь выйдет из системы, например.
Если вы по-прежнему считаете, что ядро потребляет оперативную память через модули, вы можете проверить это немного подробнее, используя:
awk '{ print $2" "$1 }' /proc/modules | sort -n
Используете ли вы ZFS? Он довольно прожорлив в плане оперативной памяти, но, как и кэш, он пытается сохранить дисковый ввод-вывод в оперативной памяти на всякий случай, если он понадобится.