Linux: Troca total usada = troca usada por processos +?

17

Então, estou tentando fazer uma investigação sobre de onde vem o uso de swap em um sistema com alto uso de swap:

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

Adicionando swap usado por 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

O que dá um valor menor para o total de swap usado. Onde está o restante espaço de troca usado? É a memória vmalloc () 'ed dentro do kernel? Algo mais? Como posso identificá-lo?

Saída de 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
    
por ninj 08.04.2013 / 17:01

2 respostas

11

A diferença que você está observando não se deve, na verdade, ao fato de o espaço de troca não ser contabilizado. O "(excluído)" que o kernel às vezes anexa a /proc/*/exe links é produzido por readlink e está causando erros de análise em seu script awk, e você está efetivamente não contando processos cujos binários não estão mais presentes em seu total. / p>

Alguns kernels acrescentam a palavra "(deleted)" aos alvos do link simbólico /proc/*/exe quando o executável original do processo não está mais disponível.

A razão pela qual seu comando está mostrando menos que o total é por causa disso. A saída de readlink em tais links será algo como "/ caminho / para / bin (excluído)", o que causa um erro de análise em awk quando a saída é substituída de volta na cadeia (não gosta da parênteses e espaços). Por exemplo, faça isso:

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

E você verá algumas entradas com "(excluído)" anexadas. Se você analisar o uso de troca para essas entradas, o total delas corresponderia à discrepância que você vê, pois os erros awk resultantes impedem que os totais sejam calculados e incluídos no total final.

Se você executar o comando original sem redirecionar o stderr para qualquer lugar, você provavelmente notará alguns erros de "constante de cadeia de fuga". Esses erros são resultado do acima e você não deveria tê-los ignorado.

Ignorando outras melhorias potenciais ao seu comando original, você poderia modificá-lo removendo o "(excluído)", assim (note |awk '{print $1}' adicionado à readlink 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"}'

Esse uso de awk para corrigir a saída de readlink pode ser interrompido se o nome contiver espaços - você pode usar sed ou qualquer método que preferir.

Informações sobre bônus

A propósito, você poderia usar apenas smem -t . A coluna "Trocar" exibe o que você deseja.

Quanto a calcular você mesmo, você também pode obter essas informações mais diretamente do campo VmSwap em /proc/*/status (o smaps requer algum suporte ao kernel e nem sempre está disponível) e evitar a necessidade de redirecionar a saída de erro usando um padrão de nome de arquivo adequado que evita os erros para começar:

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 você não precisar do binário real e puder lidar com apenas o nome do processo, poderá obter tudo em 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, finalmente, se basta ter os PIDs, basta fazer tudo com awk :

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

Nota:

Agora, isso não quer dizer que não haja diferenças entre free e smem (sendo este último o mesmo que seu script). Existem muitos (veja, por exemplo, o link , que tem resultados mais do que suficientes na primeira página para responda suas perguntas sobre o uso da memória). Mas sem um teste adequado, sua situação específica não pode ser abordada.

    
por 23.10.2013 / 00:47
5

O swap também é usado pelo tmpfs se o kernel precisar de mais RAM livre ou simplesmente porque não é usado por algum tempo ... então qualquer uso do tmpfs pode consumir swap.

    
por 21.10.2013 / 20:36