Sous Linux, comment savoir quel processus utilise le plus l'espace de swap?
Exécuter top puis appuyer sur OpEnter. Les processus doivent maintenant être triés en fonction de leur utilisation de swap.
Voici une mise à jour car ma réponse initiale ne fournit pas une réponse exacte au problème mentionné dans les commentaires. De la htop FAQ :
Il n'est pas possible d'obtenir la taille exacte de l'espace d'échange utilisé d'un processus. Top simule cette information en faisant SWAP = VIRT - RES, mais ce n'est pas une bonne mesure, car d'autres éléments tels que la mémoire vidéo sont également pris en compte sur VIRT (par exemple: top indique que mon processus X utilise 81 Mo de swap, mais également indique que mon système dans son ensemble utilise seulement 2 Mo d’échange. Par conséquent, je n’ajouterai pas de colonne d’échange similaire à htop car je ne connais pas de moyen fiable d’obtenir ces informations (en fait, je ne pense pas qu’il soit possible d’obtenir un nombre exact, à cause des pages partagées).
Le meilleur scénario que j'ai trouvé se trouve sur cette page: http://northernmost.org/blog/find-out-what-is-using-your-swap/
Voici une variante du script et aucune racine nécessaire:
#!/bin/bash
# Get current swap usage for all running processes
# Erik Ljungstrom 27/05/2011
# Modified by Mikko Rantalainen 2012-08-09
# Pipe the output to "sort -nk3" to get sorted output
# Modified by Marc Methot 2014-09-18
# removed the need for Sudo
SUM=0
OVERALL=0
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`
do
PID=`echo $DIR | cut -d / -f 3`
PROGNAME=`ps -p $PID -o comm --no-headers`
for SWAP in `grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'`
do
let SUM=$SUM+$SWAP
done
if (( $SUM > 0 )); then
echo "PID=$PID swapped $SUM KB ($PROGNAME)"
fi
let OVERALL=$OVERALL+$SUM
SUM=0
done
echo "Overall swap used: $OVERALL KB"
Voici une autre variante du script, mais destinée à donner une sortie plus lisible (vous devez l'exécuter en tant que root pour obtenir des résultats exacts):
#!/bin/bash
# find-out-what-is-using-your-swap.sh
# -- Get current swap usage for all running processes
# --
# -- rev.0.3, 2012-09-03, Jan Smid - alignment and intendation, sorting
# -- rev.0.2, 2012-08-09, Mikko Rantalainen - pipe the output to "sort -nk3" to get sorted output
# -- rev.0.1, 2011-05-27, Erik Ljungstrom - initial version
SCRIPT_NAME=`basename $0`;
SORT="kb"; # {pid|kB|name} as first parameter, [default: kb]
[ "$1" != "" ] && { SORT="$1"; }
[ ! -x `which mktemp` ] && { echo "ERROR: mktemp is not available!"; exit; }
MKTEMP=`which mktemp`;
TMP=`${MKTEMP} -d`;
[ ! -d "${TMP}" ] && { echo "ERROR: unable to create temp dir!"; exit; }
>${TMP}/${SCRIPT_NAME}.pid;
>${TMP}/${SCRIPT_NAME}.kb;
>${TMP}/${SCRIPT_NAME}.name;
SUM=0;
OVERALL=0;
echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal;
for DIR in `find /proc/ -maxdepth 1 -type d -regex "^/proc/[0-9]+"`;
do
PID=`echo $DIR | cut -d / -f 3`
PROGNAME=`ps -p $PID -o comm --no-headers`
for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'`
do
let SUM=$SUM+$SWAP
done
if (( $SUM > 0 ));
then
echo -n ".";
echo -e "${PID}\t${SUM}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.pid;
echo -e "${SUM}\t${PID}\t${PROGNAME}" >> ${TMP}/${SCRIPT_NAME}.kb;
echo -e "${PROGNAME}\t${SUM}\t${PID}" >> ${TMP}/${SCRIPT_NAME}.name;
fi
let OVERALL=$OVERALL+$SUM
SUM=0
done
echo "${OVERALL}" > ${TMP}/${SCRIPT_NAME}.overal;
echo;
echo "Overall swap used: ${OVERALL} kB";
echo "========================================";
case "${SORT}" in
name )
echo -e "name\tkB\tpid";
echo "========================================";
cat ${TMP}/${SCRIPT_NAME}.name|sort -r;
;;
kb )
echo -e "kB\tpid\tname";
echo "========================================";
cat ${TMP}/${SCRIPT_NAME}.kb|sort -rh;
;;
pid | * )
echo -e "pid\tkB\tname";
echo "========================================";
cat ${TMP}/${SCRIPT_NAME}.pid|sort -rh;
;;
esac
rm -fR "${TMP}/";
Ce n'est pas tout à fait clair si vous voulez dire que vous voulez trouver le processus qui a échangé la plupart des pages ou qui a provoqué le remplacement de la plupart des pages.
Pour le premier, vous pouvez exécuter top
et ordre par swap (appuyez sur 'Op'), pour le dernier, vous pouvez exécuter vmstat
et rechercher des entrées non nulles pour 'so'.
J'ai remarqué que ce fil est plutôt ancien, mais si vous tombez dessus, comme je viens de le faire, une autre réponse est: use smem.
Voici un lien qui vous dit à la fois comment l'installer et comment l'utiliser:
http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
Une autre variante de script évitant la boucle dans Shell:
#!/bin/bash
grep VmSwap /proc/[0-9]*/status | awk -F':' -v sort="$1" '
{
split($1,pid,"/") # Split first field on /
split($3,swp," ") # Split third field on space
cmdlinefile = "/proc/"pid[3]"/cmdline" # Build the cmdline filepath
getline pname[pid[3]] < cmdlinefile # Get the command line from pid
swap[pid[3]] = sprintf("%6i %s",swp[1],swp[2]) # Store the swap used (with unit to avoid rebuilding at print)
sum+=swp[1] # Sum the swap
}
END {
OFS="\t" # Change the output separator to tabulation
print "Pid","Swap used","Command line" # Print header
if(sort) {
getline max_pid < "/proc/sys/kernel/pid_max"
for(p=1;p<=max_pid;p++) {
if(p in pname) print p,swap[p],pname[p] # print the values
}
} else {
for(p in pname) { # Loop over all pids found
print p,swap[p],pname[p] # print the values
}
}
print "Total swap used:",sum # print the sum
}'
L'utilisation standard est script.sh
pour obtenir l'utilisation par programme avec un ordre aléatoire (jusqu'à comment awk
stocke ses hachages) ou script.sh 1
pour trier la sortie par pid.
J'espère avoir suffisamment commenté le code pour dire ce qu'il fait.
La commande top contient également un champ permettant d'afficher le nombre de défauts de page d'un processus. Le processus avec un maximum de défauts de page serait le processus qui permute le plus. Pour les démons de longue durée, il se peut qu’ils encourent un grand nombre de défauts de page au début et que le nombre n’augmente pas ultérieurement. Nous devons donc vérifier si les défauts de page augmentent.
C'est exactement la même chose que script lolotux , mais sans aucun fork pour grep
, awk
ou ps
. C'est beaucoup plus rapide!
Et comme bash est l’un des plus pauvres Shell en ce qui concerne les performances, un peu de travail a été fait pour s’assurer que ce script fonctionnera bien sous tiret , - busybox et un autre. Ensuite, ( grâce à Stéphane Chazelas ,) redevenez beaucoup plus rapide!
#!/bin/sh
# Get current swap usage for all running processes
# Felix Hauri 2016-08-05
# Rewritted without fork. Inspired by first stuff from
# Erik Ljungstrom 27/05/2011
# Modified by Mikko Rantalainen 2012-08-09
# Pipe the output to "sort -nk3" to get sorted output
# Modified by Marc Methot 2014-09-18
# removed the need for Sudo
OVERALL=0
rifs=`printf ': \t'`
for FILE in /proc/[0-9]*/status ;do
SUM=0
while IFS="$rifs" read FIELD VALUE ;do
case $FIELD in
Pid ) PID=$VALUE ;;
Name ) PROGNAME="$VALUE" ;;
VmSwap ) SUM=$((SUM=${VALUE% *})) ;;
esac
done <$FILE
[ $SUM -gt 0 ] &&
printf "PID: %9d swapped: %11d KB (%s)\n" $PID $SUM "$PROGNAME"
OVERALL=$((OVERALL+SUM))
done
printf "Total swapped memory: %14u KB\n" $OVERALL
N'oubliez pas de doubler la citation "$PROGNAME"
! Voir commentaire de Stéphane Chazelas :
read FIELD PROGNAME < <(
Perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
)
echo $FIELD "$PROGNAME"
N'essayez pas echo $PROGNAME
sans guillemet double sur le système sensible, et soyez prêt à tuer Shell avant!
Devenu un script pas si simple , il est temps d’écrire un outil dédié en utilisant un langage plus efficace.
#!/usr/bin/Perl -w
use strict;
use Getopt::Std;
my ($tot,$mtot)=(0,0);
my %procs;
my %opts;
getopt('', \%opts);
sub sortres {
return $a <=> $b if $opts{'p'};
return $procs{$a}->{'cmd'} cmp $procs{$b}->{'cmd'} if $opts{'c'};
return $procs{$a}->{'mswap'} <=> $procs{$b}->{'mswap'} if $opts{'m'};
return $procs{$a}->{'swap'} <=> $procs{$b}->{'swap'};
};
opendir my $dh,"/proc";
for my $pid (grep {/^\d+$/} readdir $dh) {
if (open my $fh,"</proc/$pid/status") {
my ($sum,$nam)=(0,"");
while (<$fh>) {
$sum+=$1 if /^VmSwap:\s+(\d+)\s/;
$nam=$1 if /^Name:\s+(\S+)/;
}
if ($sum) {
$tot+=$sum;
$procs{$pid}->{'swap'}=$sum;
$procs{$pid}->{'cmd'}=$nam;
close $fh;
if (open my $fh,"</proc/$pid/smaps") {
$sum=0;
while (<$fh>) {
$sum+=$1 if /^Swap:\s+(\d+)\s/;
};
};
$mtot+=$sum;
$procs{$pid}->{'mswap'}=$sum;
} else { close $fh; };
};
};
map {
printf "PID: %9d swapped: %11d (%11d) KB (%s)\n",
$_, $procs{$_}->{'swap'}, $procs{$_}->{'mswap'}, $procs{$_}->{'cmd'};
} sort sortres keys %procs;
printf "Total swapped memory: %14u (%11u) KB\n", $tot,$mtot;
pourrait courir avec l'un des
-c sort by command name
-p sort by pid
-m sort by swap values
by default, output is sorted by status's vmsize
J'ai adapté un script différent sur le Web à cette longue ligne:
{ date;for f in /proc/[0-9]*/status; do
awk '{k[$1]=$2} END { if (k["VmSwap:"]) print k["Pid:"],k["Name:"],k["VmSwap:"];}' $f 2>/dev/null;
done | sort -n ; }
Ce que je jette ensuite dans un cronjob et redirige la sortie vers un fichier journal. Les informations ici sont les mêmes que l'accumulation des entrées Swap:
dans le fichier smaps, mais si vous voulez en être sûr, vous pouvez utiliser:
{ date;for m in /proc/*/smaps;do
awk '/^Swap/ {s+=$2} END { if (s) print FILENAME,s }' $m 2>/dev/null;
done | tr -dc ' [0-9]\n' |sort -k 1n; }
Le résultat de cette version est en deux colonnes: pid, montant de l'échange. Dans la version ci-dessus, la tr
supprime les composants non numériques. Dans les deux cas, la sortie est triée numériquement par pid.
Sur MacOSX, vous exécutez aussi top commande mais vous devez taper "o" puis "vsize" puis ENTER.
Je suppose que vous pourriez avoir une bonne idée en exécutant top
et en recherchant des processus actifs utilisant beaucoup de mémoire. Effectuer cette opération par programme est plus difficile - il suffit de regarder les débats sans fin sur l'heuristique tueur Linux de MOO.
La permutation est une fonction de plus de mémoire utilisée active que celle installée, il est donc généralement difficile de la rejeter sur un seul processus. Si le problème persiste, la meilleure solution consiste à installer davantage de mémoire ou à apporter d'autres modifications systémiques.
Donne les totaux et les pourcentages pour le processus utilisant swap
smem -t -p
Source: https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
iotop
est un outil très utile. Il fournit des statistiques en direct sur l'utilisation des E/S et des échanges par processus/thread. Par défaut, il affiche par thread, mais vous pouvez utiliser iotop -P
pour obtenir les informations par processus. Ce n'est pas disponible par défaut. Vous devrez peut-être installer via rpm/apt.
Je ne connais pas de réponse directe quant à la manière de trouver le processus utilisant exactement l'espace d'échange. Ce lien peut toutefois être tile . Un autre bon est par ici
Utilisez également un bon outil tel que htop pour voir quels processus utilisent beaucoup de mémoire et quelle quantité de swap est utilisée dans l’ensemble.
Voici une version qui sort le même que le script de @loolotux, mais est beaucoup plus rapide (bien que moins lisible). Cette boucle prend environ 10 secondes sur ma machine, ma version prend 0,019 s, ce qui comptait pour moi parce que je voulais en faire une page cgi.
join -t / -1 3 -2 3 \
<(grep VmSwap /proc/*/status |egrep -v '/proc/self|thread-self' | sort -k3,3 --field-separator=/ ) \
<(grep -H '' --binary-files=text /proc/*/cmdline |tr '\0' ' '|cut -c 1-200|egrep -v '/proc/self|/thread-self'|sort -k3,3 --field-separator=/ ) \
| cut -d/ -f1,4,7- \
| sed 's/status//; s/cmdline//' \
| sort -h -k3,3 --field-separator=:\
| tee >(awk -F: '{s+=$3} END {printf "\nTotal Swap Usage = %.0f kB\n",s}') /dev/null