Linux: scambio totale utilizzato = scambio utilizzato dai processi +?


17

Quindi, sto provando a fare qualche indagine su da dove proviene l'uso di swap in un sistema con elevato utilizzo di swap:

# free
             total       used       free     shared    buffers     cached
Mem:        515324     508800       6524          0       4852      27576
-/+ buffers/cache:     476372      38952
Swap:       983032     503328     479704

Aggiunta di swap utilizzato per processo:

# for proc in /proc/*; do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe`'"}'; done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'
0       /bin/gawk
0       /bin/sort
0       /usr/bin/readlink
28      /sbin/xxxxxxxx
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
52      /sbin/mingetty
56      /sbin/mingetty
56      /sbin/mingetty
60      /xxxxxxxxxxx
60      /usr/sbin/xxx
84      /usr/sbin/xxx
108     /usr/bin/xxx
168     /bin/bash
220     /sbin/init
256     /sbin/rsyslogd
352     /bin/bash
356     /bin/bash
360     /usr/sbin/sshd
496     /usr/sbin/crond
672     /usr/sbin/sshd
12972   /opt/jdk1.6.0_22/bin/java
80392   /usr/libexec/mysqld
311876  /opt/jdk1.6.0_22/bin/java
408780  Total

Che dà un valore più basso per lo swap usato totale. Dov'è lo spazio di swap usato rimanente? È la memoria di vmalloc () all'interno del kernel? Qualcos'altro? Come posso identificarlo?

Uscita di meminfo:

# cat /proc/meminfo 
MemTotal:       515324 kB
MemFree:          6696 kB
Buffers:          5084 kB
Cached:          28056 kB
SwapCached:     157512 kB
Active:         429372 kB
Inactive:        65068 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:       515324 kB
LowFree:          6696 kB
SwapTotal:      983032 kB
SwapFree:       478712 kB
Dirty:             100 kB
Writeback:           0 kB
AnonPages:      399456 kB
Mapped:           8792 kB
Slab:             7744 kB
PageTables:       1820 kB
NFS_Unstable:        0 kB
Bounce:              0 kB
CommitLimit:   1240692 kB
Committed_AS:  1743904 kB
VmallocTotal:   507896 kB
VmallocUsed:      3088 kB
VmallocChunk:   504288 kB
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     4096 kB

Buffer e cache sono inclusi e non sono associati ad alcun processo.
Riccioli d'oro

2
@goldilocks: no, quelli sono nella memoria fisica. Inoltre, non si sommano.
ninj

Hai ragione, immagino che la memorizzazione nella cache di cose da scambiare sarebbe in qualche modo inutile. Tuttavia, penso che le cose che vengono scambiate possano essere lasciate lì e rintracciate anche dopo che il processo che possiede è defunto, purché lo spazio di scambio non sia altrimenti necessario; questo fa risparmiare tempo in seguito se un processo carica la stessa pagina e quindi quella pagina deve essere nuovamente scambiata - è ancora lì in scambio. La "cache di swap" di Google linux-tutorial.info/modules.php?name=MContent&pageid=314 Parallelamente al modo in cui la "cache cache" reale diventa (è roba salvata in memoria da processi ormai defunti).
Riccioli d'oro

... significa, lol, che "la memorizzazione nella cache di roba in swap" non è così inutile, solo che non ci arriva sostituendo la cache RAM.
Riccioli d'oro

1
La risposta non è solo che il kernel può scambiarsi e che non è incluso nell'elaborazione? Soprattutto il kernel ha un mucchio di processi di "spazio utente" al giorno d'oggi ... Solo una supposizione pensata.
Iain

Risposte:


11

La differenza che stai osservando non è in realtà dovuta allo spazio di swap non considerato. Il "(cancellato)" che il kernel talvolta aggiunge ai /proc/*/execollegamenti viene emesso readlinke sta causando errori di analisi nel tuo script awk e in effetti non stai contando i processi i cui binari non sono più presenti nel tuo totale.

Alcuni kernel aggiungono la parola "(cancellato)" a /proc/*/exe target dei link simbolici quando l'eseguibile originale per il processo non è più disponibile.

Il motivo per cui il tuo comando mostra meno del totale è per questo. L'output di readlinktali collegamenti sarà simile a "/ path / to / bin (cancellato)", che causa un errore di analisi inawk quando l'output viene sostituito nella stringa (non piacciono le parentesi e gli spazi). Ad esempio, procedere come segue:

for a in /proc/*/exe ; do readlink $a ; done | grep deleted

E vedrai alcune voci con "(eliminato)" aggiunto. Se osservassi l'utilizzo dello swap per queste voci, il loro totale corrisponderebbe alla discrepanza che vedi, come risultanteawk errori impediscono che i loro totali vengano calcolati e inclusi nel totale finale.

Se esegui il comando originale senza reindirizzare ovunque stderr, probabilmente noterai alcuni errori di "costante di stringa in fuga". Tali errori sono il risultato di quanto sopra e non avresti dovuto ignorarli.

Ignorando altri potenziali miglioramenti del comando originale, è possibile modificarlo rimuovendo "(eliminato)", in questo modo (nota |awk '{print $1}'aggiunta readlinkall'output):

for proc in /proc/*; \
  do cat $proc/smaps 2>/dev/null | awk '/Swap/{swap+=$2}END{print swap "\t'`readlink $proc/exe|awk '{print $1}' `'" }'; \
done | sort -n | awk '{total+=$1}/[0-9]/;END{print total "\tTotal"}'

Questo uso di awkper correggere l'output di readlinkpotrebbe interrompersi se il nome contiene spazi: è possibile utilizzare sedo il metodo che preferisci.

Informazioni sul bonus

A proposito, potresti semplicemente usare smem -t. La colonna "Scambia" mostra ciò che desideri.

Per quanto riguarda il calcolo da soli, tuttavia, puoi anche ottenere queste informazioni più direttamente dal VmSwapcampo in /proc/*/status(smaps richiede un po 'di supporto del kernel e non è sempre disponibile), ed evita di reindirizzare l'output dell'errore utilizzando un modello di nome file appropriato che evita il errori per cominciare:

for proc in /proc/[0-9]*; do \
  awk '/VmSwap/ { print $2 "\t'`readlink $proc/exe | awk '{ print $1 }'`'" }' $proc/status; \
done | sort -n | awk '{ total += $1 ; print $0 } END { print total "\tTotal" }'

Se non hai bisogno dell'attuale binario e riesci a gestire solo il nome del processo, puoi ottenere tutto da status:

for a in /proc/*/status ; do \
  awk '/VmSwap|Name/ { printf $2 " " } END { print "" }' $a ; \
done | awk '{ total+=$2 ; print $0 } END { print "Total " total }'

E infine, se basta avere i PID, puoi fare tutto con awk:

awk '/VmSwap/ { total += $2; print $2 "\t" FILENAME } END { print total "\tTotal" }' /proc/*/status

Nota:

Questo non vuol dire che non ci siano differenze tra freee smem(quest'ultima essendo la stessa della tua sceneggiatura). Ce ne sono molti (vedi, ad esempio, https://www.google.com/search?q=smem+free , che ha risultati più che sufficienti nella prima pagina per rispondere alle tue domande sull'utilizzo della memoria). Ma senza un test adeguato, la tua situazione specifica non può essere affrontata.


5

Lo swap è anche usato dai tmpfs se il kernel ha bisogno di più ram gratuiti o semplicemente perché non è in uso da qualche tempo ... quindi qualsiasi utilizzo di tmpfs potrebbe consumare swap.


1
Perché il downvote? Questo è assolutamente corretto.
jlliagre,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.