«Ест много памяти» и «течёт» — разные проблемы. Утечка это процесс, у которого RSS равномерно растёт и никогда не падает, в том числе когда машина простаивает. Один снимок этого не покажет — нужны два, разнесённые во времени.
1. Кто самый крупный прямо сейчас
$ clai покажи процессы, отсортированные по потреблению памяти→ ps -eo pid,comm,rss,%mem --sort=-rss | head -4 PID COMMAND RSS %MEM 218979 firefox 2089376 3.1 269458 verba 1257196 1.9 727108 telegram 1249824 1.9
RSS указан в килобайтах и это та цифра, которая важна: физическая память, реально занятая процессом. Перед вами список подозреваемых, а не ответ.
2. Понаблюдать за одним процессом во времени
$ clai снимай память процесса 269458 каждые 10 секунд, 6 раз→ pidstat -r -p 269458 10 6
Вот это и есть проверка. Рост RSS во всех шести замерах при ровной нагрузке — утечка. Рост с выходом на полку — заполняется кэш, это нормально и само остановится.
3. Дешёвые замеры без лишних пакетов
$ clai пиши память этого процесса в файл каждую минуту→ while sleep 60; do printf '%s %s\n' "$(date +%T)" "$(grep VmRSS /proc/269458/status)"; done | tee mem.logVmRSS: 1257196 kB
pidstat живёт в пакете sysstat, который стоит не везде. /proc/<pid>/status есть всегда. Оставьте на час — и форма ответа станет очевидной.
4. Куда именно внутри процесса ушла память
$ clai покажи карту памяти процесса 269458, отсортированную по размеру→ sudo pmap -x 269458 | sort -k3 -rn | head
Одно анонимное отображение, выросшее между двумя запусками pmap, — это куча. Множество мелких отображений, которые всё прибавляются, обычно означают утёкшие стеки потоков или незакрытые файлы под mmap.
5. Сначала исключить файловый кэш
$ clai покажи использование памяти без учёта кэша и буферов→ free -h total used free shared buff/cache availableMem: 62Gi 18Gi 2.1Gi 1.2Gi 42Gi 43Gi
Смотрите на available, а не на free. Linux намеренно забивает свободную память страничным кэшем и отдаёт её по требованию. «Свободно всего 2 ГБ» при 43 ГБ available — это здоровая система, а не утечка.
6. Убедиться, что дело в процессе, а не в машине
$ clai проверь, убивало ли ядро процессы из-за нехватки памяти→ sudo dmesg -T | grep -i 'killed process'
Если сработал OOM killer, ядро называет выбранный процесс и его память на тот момент. Это самое надёжное подтверждение, какое можно получить, и оно уже записано за вас.
Грабли
- RSS дважды считает разделяемую память. Два процесса с общей библиотекой оба показывают её страницы. Для честной цифры на процесс берите PSS из
smemили/proc/<pid>/smaps_rollup. - Перезапуск — это обход, а не диагноз. Он обнуляет график и прячет улики. Сначала замеры, потом перезапуск.
- Лимиты контейнера изнутри не видны. Процесс в контейнере видит в
freeвсю память хоста; настоящий потолок лежит в/sys/fs/cgroup/memory.max.
Похожие вопросы
Какой рост считать утечкой? Любой устойчивый подъём при неизменной нагрузке. Процесс, который прибавляет 50 МБ в час и ничего не отдаёт, рано или поздно поймает OOM killer, сколько бы памяти вы ни добавили.
Высокое потребление памяти в Linux — это плохо? Само по себе нет. Неиспользуемая память — потраченная впустую: ядро держит в ней кэш и освобождает под нагрузкой. Следите за available и за активностью подкачки.
Каким инструментом искать утекающую строку кода? Valgrind (--leak-check=full) для C и C++ либо профилировщик кучи вашего языка. Команды отсюда находят, какой процесс; чинить его — другая история.
Читайте также
- «Кто жрёт CPU прямо сейчас?» — мониторинг системы по-человечески
- Убить процесс на порту 8080 — и другое, что вечно гуглишь
- df говорит, что диск полон, du — что нет
Скажите, что хотите измерить, — вызов pidstat со всеми флагами напишет CliAI. Установка одной строкой.