top и htop — что показывают и как читать
Когда сервер “тормозит”, первое, что делает любой инженер — открывает top или htop. Это интерактивный показ системы в реальном времени: какие процессы едят CPU/память, какая нагрузка, сколько свободной памяти. Но эти утилиты выдают много информации, и Junior часто смотрит на цифры, не понимая что они значат. “Load average 8” — это плохо или хорошо? “wa: 60%” — что это? “buff/cache: 12 ГБ” — куда делась RAM?
В этом уроке: разберём каждое поле top, разницу с htop, ключевые метрики — load average, CPU breakdown (us/sy/wa/st), memory accounting, и научимся быстро находить проблемного “виновника”.
top: классический скрин
Запускаем top (запускается с любого Linux/Unix без установки):
Полный пример вывода:
top - 14:32:18 up 23 days, 4:12, 3 users, load average: 1.42, 1.05, 0.87
Tasks: 287 total, 2 running, 285 sleeping, 0 stopped, 0 zombie
%Cpu(s): 8.3 us, 2.1 sy, 0.0 ni, 88.5 id, 0.8 wa, 0.0 hi, 0.3 si, 0.0 st
MiB Mem : 31987.4 total, 3214.5 free, 18756.2 used, 10016.7 buff/cache
MiB Swap: 8192.0 total, 8192.0 free, 0.0 used. 12345.1 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 postgres 20 0 524288 281456 35216 S 35.2 0.9 2:45.67 postgres: writer
5678 lev 20 0 8567432 2345678 456789 S 12.4 7.2 45:23.12 firefox
9012 root 20 0 0 0 0 I 0.7 0.0 0:23.45 kworker/u8:2
Header line 1: load average
top - 14:32:18 up 23 days, 4:12, 3 users, load average: 1.42, 1.05, 0.87
14:32:18— текущее время.up 23 days, 4:12— uptime сервера.3 users— сколько user-sessions активно (через SSH, локальные).- load average: 1.42, 1.05, 0.87 — среднее за 1, 5, 15 минут.
Load average — одна из самых неправильно интерпретируемых метрик. Это среднее число процессов в состоянии runnable или uninterruptible (D state) в последние 1/5/15 минут.
Правильная интерпретация: если у вас 4 CPU и load = 4 — это полная утилизация, 100%. Load = 8 на 4 CPU — система перегружена (процессы стоят в очереди на CPU). Load = 2 на 4 CPU — нормально.
# Сколько CPU:
nproc
4
# load average:
uptime
14:32:18 up 23 days, 4:12, 3 users, load average: 1.42, 1.05, 0.87
# Интерпретация:
# 1.42 на 4 CPU = 35% utilization, идеально
# Если 1, 5, 15 близки -- стабильная нагрузка
# Если 1-min >> 15-min -- нагрузка растёт прямо сейчас
# Если 1-min << 15-min -- нагрузка падает
ВНИМАНИЕ: load включает процессы в D state (uninterruptible sleep — обычно IO). Если у вас load=20 при 4 CPU, и при этом CPU% низкий — значит 16 процессов застряли в IO. Это IO bottleneck, а не CPU. Проверять vmstat, iostat (урок 14.2).
Header line 2: tasks
Tasks: 287 total, 2 running, 285 sleeping, 0 stopped, 0 zombie
- total — всего процессов.
- running — сейчас на CPU или ready to run. Высокое число (>2-3) намекает на CPU bottleneck.
- sleeping — ждут события (IO, signal, syscall). Норма.
- stopped — остановлены SIGSTOP/SIGTSTP.
- zombie — умерли, но родитель не reap-нул через wait(). Несколько — ОК, много — баг в родителе (не вызывает waitpid).
Header line 3: CPU breakdown
Самая важная и непонятная строка для Junior.
%Cpu(s): 8.3 us, 2.1 sy, 0.0 ni, 88.5 id, 0.8 wa, 0.0 hi, 0.3 si, 0.0 st
Эти проценты в сумме дают 100% времени CPU. Это усреднение по всем CPU.
Что важно запомнить (по симптомам):
- us высокий (>80%) — CPU bottleneck в приложениях. Профилировать через
perf top(урок 14.4). - sy высокий (>20%) — много syscalls.
strace -p PID -cнайти что часто вызывается. - wa высокий (>30%) — disk IO bottleneck. Идти в
iostat -x 1, смотретьawait,%util. - st > 0 на cloud VM — проверить, что соседи не шумят. Высокий st = ваша VM throttled.
- si высокий — много network traffic (мирится с iptables, NIC interrupts).
Header lines 4-5: память
MiB Mem : 31987.4 total, 3214.5 free, 18756.2 used, 10016.7 buff/cache
MiB Swap: 8192.0 total, 8192.0 free, 0.0 used. 12345.1 avail Mem
- total — сколько RAM физически (31.2 GiB).
- free — неиспользуемая память. Часто маленькая — НЕ ЗНАЧИТ что плохо.
- used — занято приложениями и kernel.
- buff/cache — page cache + buffers. Это занятая память, но “оппортунистически” — kernel освобождает её под нужду.
- avail Mem — сколько РЕАЛЬНО можно дать новому процессу без swap (free + reclaimable buff/cache). Это самая важная метрика!
‘Linux ate my RAM!’ — классическое замешательство. После часов работы free показывает маленькое число (потому что kernel держит buff/cache). Это НЕ memory leak — это нормальное поведение. Когда какой-то процесс запросит память, kernel освободит buff/cache. Смотрите ‘available’ — вот сколько на самом деле есть.
Swap: total/free/used. used > 0 значит что часть памяти ушла на диск — система начала свопить. Это сильно медленнее RAM (100-1000x). Постоянный swap usage — сигнал что памяти не хватает физически.
Task list: одна строка на процесс
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 postgres 20 0 524288 281456 35216 S 35.2 0.9 2:45.67 postgres: writer
Расшифруем поля:
- PID — process ID.
- USER — от какого юзера.
- PR — priority (системный приоритет; 20 — норма; -20 (RT) до 39).
- NI — nice (приоритет в userspace; от -20 до +19, дефолт 0).
- VIRT — virtual size: вся виртуальная память процесса (включая зашифрованную, mmap, shared, libraries). На современных системах огромное число (десятки GB) — НЕ значит что столько физически занято.
- RES — resident set size (RSS): сколько физической RAM реально занято. Это то, что вы должны смотреть.
- SHR — shared memory: shared библиотеки, shm. Может делиться между процессами.
- S — state: R (running), S (sleeping), D (disk wait, uninterruptible), Z (zombie), T (stopped), I (idle kernel thread).
- %CPU — доля CPU времени. На multi-core может быть > 100% (100% = 1 CPU full).
- %MEM — доля RAM от total.
- TIME+ — CPU time с момента start (не wall clock!).
- COMMAND — имя/команда.
Состояния процессов: что значит каждое
| S | Расшифровка | Когда видим |
|---|---|---|
| R | Running / runnable | Активный процесс |
| S | Sleeping | Ждёт что-то (IO, sleep, select) — большинство процессов |
| D | Disk wait / uninterruptible | Застрял в kernel-коде IO; не реагирует на SIGTERM/SIGKILL |
| Z | Zombie | Умер, родитель не сделал wait() |
| T | Stopped | SIGSTOP/SIGTSTP получен |
| I | Idle kernel thread | kworker, kthread спит |
D state особенно опасен: процесс нельзя убить, и он считается в load average. Если много D-процессов — проверяйте disk health (smartctl, dmesg).
Полезные клавиши в top
Top интерактивен. Внутри:
h— help (полный список).q— quit.Shift+P— сортировка по CPU% (default).Shift+M— сортировка по %MEM.Shift+T— сортировка по TIME+.c— toggle: command line полная или короткая.1— toggle: видеть каждый CPU отдельно или среднее.f— выбор полей (что показывать).k— kill процесс (введите PID, потом сигнал).r— renice процесс (изменить приоритет).u— фильтр по юзеру.
htop — усовершенствованный top
htop — не в стандарте, надо установить (apt install htop). Но он на порядок удобнее:
- Цветной вывод.
- Bar-графики для CPU и памяти.
- Mouse support: клик чтобы выделить, сортировать, kill.
- Tree view (F5): показать parent-child иерархию процессов.
- Сразу видны все CPU отдельно (не нужно нажимать “1”).
- F-keys для частых операций (F9 kill, F7/F8 renice).
В целом, для повседневной работы htop удобнее, но top везде есть.
top и htop в повседневной работе: практические шорткатыReal-world сценарии
Сценарий 1: сервер тормозит, ssh лагает.
load average: 25.43, 18.21, 9.45 <-- 25 на 4 CPU -- очень плохо
%Cpu(s): 60 us, 5 sy, 30 wa, 5 id <-- 30% iowait!
Высокий iowait + высокий load = диск перегружен. Идти в iostat -x 1 (урок 14.2), искать виновника. Возможно, рост работы (постгрес vacuum?), или диск умирает.
Сценарий 2: память кончается.
MiB Mem: 32000 total, 200 free, 28000 used, 3800 buff/cache
MiB Swap: 8000 total, 4500 free, 3500 used. 4500 avail Mem
Swap used = 3.5 GB — система начала свопить. Available 4.5 GB — ОК пока. Найти память-жора через Shift+M. Возможно, увеличить RAM или найти memory leak.
Сценарий 3: zombie процессы накапливаются.
Tasks: 287 total, 1 running, 200 sleeping, 86 zombie
86 zombies — баг в каком-то supervisor: он fork-нул детей и не вызвал wait(). Найти parent: ps -A -ostat,ppid,pid,cmd | grep -e '^[Zz]'. Перезапустить parent.
Сценарий 4: один CPU на 100%, остальные idle.
Нажмите 1 в top чтобы видеть каждое CPU. Если один CPU 100%, остальные idle — это single-threaded приложение. Возможно, нужно использовать multiprocessing.
Попробуй сам
# 1. Откройте top:
top
# Поэкспериментируйте: Shift+M, Shift+P, 1, q
# 2. Установите htop если нет:
sudo apt install htop
htop
# 3. Узнайте свой load и nproc:
uptime
nproc
# 4. Memory deep dive:
free -h
cat /proc/meminfo | head -20
# 5. Сколько процессов в каждом state:
ps -A -ostat | sort | uniq -c
# 6. Сколько в D state (потенциально проблема):
ps -A -ostat,pid,cmd | awk '$1=="D"'
# 7. Сколько zombie:
ps -A -ostat | grep -c Z
# 8. Топ 5 по CPU без интерактива:
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head -6
# 9. Топ 5 по RSS:
ps -eo pid,user,rss,vsz,comm --sort=-rss | head -6
Анатомия экрана htop — что видно сразу
Главные преимущества htop над top на практике:
- Видишь все CPU сразу — moment понять single-thread vs parallel.
- Tree view (F5) — видишь parent-child. Postgres root -> children. Один gunicorn -> 8 workers.
- Поиск (F3) — быстрее найти процесс по имени, не перелистывать.
- Filter (F4) — скрыть всё кроме interesting.
- Mouse + clicks — редко на сервере, но на dev-машине удобно.