Salta al contenuto principale

top: cosa sta usando il computer, in tempo reale

Inviato da tuxsa il

Il server è lento: ma perché? È il processore sotto sforzo, la memoria finita, o un solo programma impazzito? top mostra, aggiornandolo di continuo, lo stato del sistema e l'elenco dei processi ordinato per consumo di risorse: è il primo comando da lanciare quando qualcosa "non gira come dovrebbe".

Cos'è

top fa parte del pacchetto procps, ed è presente su ogni distribuzione Linux, anche in quelle più minimali. È un programma interattivo: occupa il terminale, si aggiorna ogni pochi secondi e risponde ai tasti. Mentre ps (visto in un articolo precedente) scatta una fotografia dei processi, top è un video in diretta. Per uscire basta premere q.

Cosa fa

Ogni 3 secondi (valore predefinito) legge dal sistema lo stato del computer e lo mostra in due parti: in alto un riepilogo (da quanto è acceso il computer, carico, processi, processore, memoria) e sotto la tabella dei processi, con il consumo di ognuno. Permette di cambiare l'ordinamento, filtrare, e perfino terminare un processo, senza uscire dal programma.

Come si usa

$ top [opzioni]

Non servono privilegi per vedere tutti i processi (anche quelli degli altri utenti); servono, invece, per fermarli o modificarne la priorità. Gli esempi mostrano un server virtuale con 4 processori e 8 GB di memoria.

Esempio 1: la schermata di top

$ top
top - 07:46:09 up 63 days,  2:15,  1 user,  load average: 0.52, 0.48, 0.44
Tasks: 142 total,   1 running, 141 sleeping,   0 stopped,   0 zombie
%Cpu(s):  6.3 us,  2.1 sy,  0.0 ni, 91.0 id,  0.4 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :   7953.5 total,    812.3 free,   3105.8 used,   4035.4 buff/cache
MiB Swap:   2048.0 total,   2040.1 free,      7.9 used.   4559.6 avail Mem

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   1034 mysql     20   0 2380128 412336  38912 S  12.3   5.1  91:44.20 mariadbd
    925 www-data  20   0  145220  12044   8120 S   3.0   0.1   7:15.31 nginx
   4410 enzo      20   0  452300  86400  21980 S   1.7   1.1   0:42.77 python3
    801 root      20   0   15440   8812   7240 S   0.3   0.1   0:12.05 sshd
      1 root      20   0  168192  12364   8412 S   0.0   0.2   0:35.60 systemd

Le etichette e i decimali dipendono dalla lingua del sistema (in italiano si vedono virgole al posto dei punti). Le righe del riepilogo, una per una:

  • Prima riga: ora, da quanto tempo il computer è acceso (up 63 days), utenti collegati e il load average, il carico medio degli ultimi 1, 5 e 15 minuti (vedi l'esempio 4).
  • Tasks: processi totali, in esecuzione (running), in attesa (sleeping), fermi (stopped) e zombie.
  • %Cpu(s): come viene usato il processore, in percentuale: us programmi degli utenti, sy sistema operativo (kernel), ni programmi a bassa priorità, id inattivo (idle), wa attesa di dischi e rete (I/O wait), hi e si interruzioni hardware e software, st tempo "rubato" dalla macchina fisica ai server virtuali (steal).
  • MiB Mem e MiB Swap: memoria totale, libera, usata e usata come cache, e lo spazio su disco usato come memoria di riserva (swap). Il valore da guardare è avail Mem (vedi l'esempio 5).

La tabella sotto ha una riga per processo: PID numero identificativo, USER proprietario, PR e NI priorità, VIRT, RES e SHR memoria (vedi più avanti), S stato, %CPU e %MEM percentuali di processore e memoria, TIME+ tempo di processore totale usato e COMMAND il nome del programma.

Esempio 2: i tasti da conoscere

q          esce
h          guida con tutti i tasti
P          ordina per uso del processore (predefinito)
M          ordina per uso della memoria
T          ordina per tempo di processore accumulato
N          ordina per PID
R          inverte l'ordine
c          mostra la riga di comando completa di ogni processo
1          mostra il carico di ogni singolo processore
u          mostra solo i processi di un utente (chiede il nome)
k          termina un processo (chiede PID e segnale)
r          cambia la priorità (nice) di un processo
d  oppure s   cambia l'intervallo di aggiornamento
spazio     aggiorna subito
W          salva le impostazioni correnti

Si usano mentre top è in esecuzione. Distinguono le maiuscole dalle minuscole: M (maiuscola) ordina per memoria, m (minuscola) cambia il modo in cui si mostra la memoria. Il tasto più utile in pratica è c: il solo nome python3 o java non dice quale programma sia, la riga di comando completa sì. E con 1 si scopre se un solo processore è saturo mentre gli altri sono liberi.

Esempio 3: chi sta consumando? Cercare il colpevole

(avvia top, poi:)
P       il primo della lista è il maggiore consumatore di processore
M       il primo della lista è il maggiore consumatore di memoria
c       mostra il comando completo
u       digita "www-data" e Invio, per vedere solo quell'utente
k       digita il PID e Invio, poi Invio per il segnale 15 (TERM)

Il metodo più rapido per trovare un processo che rallenta il computer: ordina per P (processore) o M (memoria), guarda i primi della lista e premi c per capire cosa sono. Con k si può terminare un processo: top chiede il PID e poi il segnale (il valore predefinito è 15, la richiesta gentile di chiusura; 9 è la chiusura forzata). Vedi l'articolo su ps e kill per capire la differenza. Prima di fermare un processo di sistema, controlla di sapere cos'è.

Esempio 4: il load average

$ uptime
 07:46:09 up 63 days,  2:15,  1 user,  load average: 0.52, 0.48, 0.44
$ nproc
4
$ cat /proc/loadavg
0.52 0.48 0.44 1/142 31877

Il load average indica quanti processi, in media, erano in esecuzione o in attesa di poterlo fare nell'ultimo minuto, nei 5 minuti e nei 15 minuti. Va letto in rapporto al numero di processori, che si ottiene con nproc: su un computer con 4 core, un carico di 4.00 significa che sono tutti occupati; sopra questo valore i processi fanno la fila. Tre numeri servono a capire la tendenza: se il primo (1 minuto) è molto più alto degli altri, il carico sta salendo adesso; se è più basso, sta scendendo. Un carico alto con il processore quasi inattivo (id alto) spesso indica un problema di dischi o di rete (wa alto): i processi aspettano i dati. Gli stessi valori si leggono con uptime e in /proc/loadavg.

Esempio 5: leggere la memoria senza spaventarsi

MiB Mem :   7953.5 total,    812.3 free,   3105.8 used,   4035.4 buff/cache
MiB Swap:   2048.0 total,   2040.1 free,      7.9 used.   4559.6 avail Mem

Linux usa la memoria libera come cache per i file letti di recente, e la restituisce ai programmi appena serve. Per questo free basso e buff/cache alto sono normali: non significano che la memoria sia finita. Il valore da guardare è avail Mem (disponibile): la quantità che i programmi possono davvero ottenere senza ricorrere allo swap. Nell'esempio sono circa 4,5 GB su 8, quindi la situazione è tranquilla. Segnali di guaio: avail Mem vicino a zero, un uso crescente dello swap (la memoria su disco, molto più lenta) e processi che il sistema chiude da solo quando la memoria finisce (nei registri compare "Out of memory"). Per la memoria vista in dettaglio c'è free.

Anche le colonne dei processi hanno un significato preciso: VIRT è la memoria "prenotata", che spesso non è usata davvero e non è un valore su cui preoccuparsi, RES è la memoria fisica effettivamente occupata dal processo (il numero da tenere d'occhio), e SHR la parte condivisa con altri processi.

Esempio 6: gli stati dei processi

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
   4410 enzo      20   0  452300  86400  21980 R  98.7   1.1   0:42.77 python3
   1034 mysql     20   0 2380128 412336  38912 S   2.3   5.1  91:44.20 mariadbd
   7788 enzo      20   0   10224   3120   2780 D   0.7   0.0   0:00.31 rsync
  31877 enzo      20   0       0      0      0 Z   0.0   0.0   0:00.00 lavoro <defunct>

La colonna S dice cosa sta facendo il processo: R è in esecuzione, S dorme in attesa di qualcosa (lo stato più comune, e normale), D è in attesa di operazioni su disco o rete e non può essere interrotto, T è fermato, Z è uno zombie (è terminato ma il suo "genitore" non ha ancora raccolto il risultato, e compare come <defunct>) e I è un processo del kernel inattivo. Pochi D che scompaiono subito sono normali; dei D che restano a lungo indicano un problema di disco o di rete. Uno zombie non consuma risorse e non si può "uccidere": si risolve terminando o riavviando il processo genitore.

Esempio 7: opzioni all'avvio

$ top -u www-data
$ top -p 925,1034
$ top -p $(pgrep -d, nginx)
$ top -d 1
$ top -o %MEM
$ top -c
$ top -H -p 1034

Le opzioni più utili: -u utente mostra solo i processi di un utente; -p mostra solo i processi con quei PID (separati da virgole); con pgrep -d, nome si ottiene l'elenco dei PID di un programma, separati da virgole, già nel formato giusto; -d secondi cambia l'intervallo di aggiornamento; -o campo sceglie l'ordinamento iniziale (%MEM, %CPU, TIME+); -c mostra la riga di comando completa; -H mostra i singoli thread invece dei processi (un programma con molti thread, come un database, appare così in dettaglio).

Esempio 8: top in "modalità batch", per i registri e gli script

$ top -b -n 1 | head -n 15
$ top -b -n 2 -d 1 | awk '/^top -/ {n++} n==2' | head -n 15
$ top -b -n 1 -o %MEM | sed -n '7,12p'
$ top -b -d 60 -n 5 -w 160 >> /var/log/top-prove.log

Con -b (batch) top non è più interattivo: stampa il suo output come testo normale, che si può reindirizzare in un file o passare a head, grep o awk. -n dice quante volte aggiornare prima di uscire (-n 1 una sola schermata), e -w imposta la larghezza (altrimenti l'output viene tagliato a 80 colonne). Attenzione: la prima schermata mostra le percentuali di processore calcolate dall'avvio del processo, non dell'ultimo istante. Per valori attuali servono almeno due giri: con -n 2 si tiene solo il secondo, e nell'esempio awk numera le schermate (ogni giro comincia con una riga top -) e stampa solo la seconda. Il comando, mettendo in un file l'output ogni minuto, serve a ricostruire cosa è successo durante un rallentamento della notte.

Esempio 9: uso negli script

#!/bin/bash
CORES=$(nproc)
LOAD=$(cut -d' ' -f1 /proc/loadavg)

if awk -v l="$LOAD" -v c="$CORES" 'BEGIN {exit !(l > c)}'; then
    echo "$(date '+%F %T') carico alto: $LOAD su $CORES core" >> "$HOME/carico.log"
    top -b -n 2 -d 1 -o %CPU | awk '/^top -/ {n++} n==2' \
        | sed -n '7,14p' >> "$HOME/carico.log"
fi

Un piccolo controllo da lanciare ogni pochi minuti con crontab: legge il carico dal file /proc/loadavg (più semplice da elaborare dell'output di top), lo confronta con il numero di core usando awk (la shell non sa confrontare numeri decimali) e, solo se è troppo alto, salva nel registro la data e i primi processi della classifica. Così, quando qualcuno dice "ieri alle tre il sito era lentissimo", c'è già la risposta con i nomi dei processi coinvolti.

Esempio 10: alternative più comode

$ sudo apt install htop
$ htop
$ ps aux --sort=-%cpu | head -n 5
$ ps aux --sort=-%mem | head -n 5
$ vmstat 1 5
$ watch -n 2 'ps aux --sort=-%cpu | head -n 6'

htop è una versione a colori e più comoda di top: barre per ogni processore, ricerca, filtri e la possibilità di usare il mouse, e per questo molti lo preferiscono (si installa con apt; ne esistono altre ancora più ricche, come btop). Per un'istantanea ordinata basta ps aux --sort=-%cpu (vedi l'articolo su ps). vmstat 1 5 mostra cinque misure, una al secondo, di processi, memoria, swap, dischi e processore; e con watch si ripete qualunque comando a intervalli. Per sapere quali programmi stanno usando il disco serve iotop; per la rete, nethogs o ss.

Opzioni utili

  • -u utente / -p pid,pid: solo i processi di un utente / con quei PID.
  • -d secondi: intervallo di aggiornamento; -n N: numero di aggiornamenti prima di uscire.
  • -b: modalità batch (testo, non interattiva); -w colonne: larghezza dell'output in batch.
  • -o campo: ordinamento iniziale (%CPU, %MEM, TIME+…); -O: elenca i campi disponibili.
  • -c: riga di comando completa; -H: mostra i thread; -i: nasconde i processi inattivi; -S: tempi cumulativi.
  • -E k|m|g / -e k|m|g: unità della memoria nel riepilogo / nei processi.
  • Tasti: P M T N (ordina), R (inverte), c (comandi), 1 (singoli core), u (utente), k (termina), r (priorità), V (vista ad albero), f (scelta delle colonne), W (salva), h (guida), q (esci).
  • Strumenti collegati: htop, uptime, free, vmstat, iotop, ps, pgrep.

Attenzione a

  • k uccide davvero: top non chiede conferma dopo l'inserimento del PID e del segnale. Controlla bene il PID, e non fermare processi di sistema o di cui non sai la funzione (sshd, systemd, il database). Per i servizi, meglio systemctl.
  • La prima schermata è ingannevole: i valori di %CPU della prima schermata sono medie dall'avvio del processo. Aspetta il secondo aggiornamento, e in modalità batch usa -n 2.
  • %CPU può superare 100: per default il 100% è un singolo processore, quindi un processo con più thread su 4 core può arrivare a 400%. Con I (maiuscola) si passa a una percentuale sul totale dei processori.
  • "Poca memoria libera" non è un problema: guarda avail Mem, non free. Il valore di VIRT è irrilevante nella maggior parte dei casi.
  • Un load average alto non vuol dire per forza processore saturo: su Linux conta anche chi aspetta il disco (stato D). Se il carico è alto e il processore è in gran parte inattivo, il problema è nei dischi o nella rete; guarda wa. Un st alto, in un server virtuale, vuol dire che è la macchina fisica a essere sovraccarica, e non il tuo server.
  • Nei container e nelle macchine virtuali condivise: dentro un container Docker, top può mostrare il carico e la memoria della macchina ospite, non quelli assegnati al container. Per le risorse di un container serve docker stats.
  • La riga di comando può contenere segreti: con c o -c si vedono gli argomenti dei programmi, e se qualcuno ha scritto una password o un token nel comando (come mysql -pSEGRETO), compare a schermo e negli output salvati. Vale anche per tutti gli altri utenti del sistema.
  • Lasciare top aperto: consuma poco, ma su una connessione ssh lenta ogni aggiornamento invia dati. E nei server condivisi ricorda di uscire con q. Non lasciarlo in esecuzione in tmux o screen per giorni, se non ti serve.
  • Un programma che sparisce prima di averlo visto: top aggiorna ogni 3 secondi, e un processo che consuma moltissimo per pochi istanti può non comparire mai. Per i lavori molto brevi servono strumenti di registrazione (come sar) o l'esame dei registri di sistema con journalctl.
  • Le impostazioni salvate con W vanno nel file ~/.config/procps/toprc e valgono per le prossime esecuzioni: se top "si comporta in modo strano" (colonne diverse, ordine diverso), può dipendere da lì. Si ripristina cancellando il file.
  • Non è un sostituto del monitoraggio: top mostra solo il momento in cui lo guardi. Per tenere sotto controllo un server nel tempo servono registri e strumenti dedicati (come sar, netdata, Prometheus con Grafana).

Riepilogo

Comando / tastoCosa fa
topMostra processi e risorse in tempo reale
qEsce
P / M / TOrdina per processore / memoria / tempo
cMostra la riga di comando completa
1Mostra ogni singolo processore
uFiltra per utente
kTermina un processo (chiede PID e segnale)
top -u utenteSolo i processi di un utente
top -p 925,1034Solo i processi con quei PID
top -d 1Aggiorna ogni secondo
top -o %MEMParte ordinato per memoria
top -b -n 2 -d 1Output testuale (due giri), per script e registri
uptime / nprocCarico medio / numero di processori
htopAlternativa a colori, più comoda