Comment savoir quels processus utilisent l'espace de pagination sous Linux?

sous Linux, comment savoir quel processus utilise le plus l'espace de pagination?

214
demandé sur Thorbjørn Ravn Andersen 2009-01-26 17:29:57

14 réponses

Exécuter top puis appuyez sur O p Entrée . Maintenant, les processus doivent être triés en fonction de leur pagination.

Voici une mise à jour car ma réponse originale ne fournit pas une réponse exacte au problème comme souligné dans les commentaires. De la HTOP FAQ :

il n'est pas possible d'obtenir la taille exacte de l'espace d'échange utilisé de un processus. Top falsifie cette information en faisant SWAP = VIRT-RES, mais ce n'est pas une bonne métrique, parce que d'autres choses comme la mémoire vidéo compte sur VIRT aussi bien (par exemple: top dit que mon processus X utilise 81M de swap, mais il signale également que mon système dans son ensemble utilise seulement 2M de swap. Par conséquent, je n'ajouterai pas de colonne de Swap similaire à htop parce que je ne sais pas un moyen fiable pour obtenir cette information (en fait, Je ne pense pas qu'il soit possible d'obtenir un nombre exact, en raison de partagé page.)

95
répondu David Holm 2015-10-03 09:24:30

le meilleur script que j'ai trouvé est 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  }'`
    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"
276
répondu lolotux 2014-09-18 21:04:59

Voici une autre variante du script, mais destinée à donner une sortie plus lisible (vous devez exécuter ceci 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 "151900920"`;
SORT="kb";                 # {pid|kB|name} as first parameter, [default: kb]
[ "" != "" ] && { SORT=""; }

[ ! -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  }'`
    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}/";
50
répondu j3nda 2017-02-03 00:23:20

ce n'est pas tout à fait clair si vous voulez dire que vous voulez trouver le processus qui a la plupart des pages échangées ou le processus qui a causé la plupart des pages échangées.

pour le premier vous pouvez lancer top et commander par swap (appuyez sur 'Op'), pour le second vous pouvez lancer vmstat et rechercher des entrées non nulles pour 'so'.

10
répondu Ronny Vindenes 2009-01-26 14:54:09

j'ai remarqué que ce fil est assez vieux, mais si vous tombez dessus, comme je viens de le faire, une autre réponse est: utilisez smem.

Voici un lien qui t'explique comment l'installer et comment l'utiliser:

http://www.cyberciti.biz/faq/linux-which-process-is-using-swap /

9
répondu Tom 2014-10-06 12:36:22

Le haut commandement contient également un champ pour afficher le nombre de défauts de page pour un processus. Le processus avec le maximum de défauts de page serait le processus qui échange le plus. Pour de longues démons, il pourrait être qu'ils engagent un grand nombre de défauts de page au début et le nombre n'augmente pas plus tard. Nous devons donc observer si les défauts de la page augmentent.

6
répondu Amol Kulkarni 2012-07-27 07:31:15

une autre variante de script évitant la boucle dans shell:

#!/bin/bash
grep VmSwap /proc/[0-9]*/status | awk -F':' -v sort="" '
  {
    split(,pid,"/") # Split first field on /
    split(,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
  }'

utilisation Standard est script.sh pour obtenir l'utilisation par programme avec ordre aléatoire (jusqu'à comment awk stocke ses hachures) ou script.sh 1 pour trier la sortie par pid.

j'espère que j'ai assez commenté le code pour dire ce qu'il fait.

5
répondu Tensibai 2016-08-22 11:40:14

encore deux variantes:

Un variante! (Pas de bash uniquement)

c'est exactement la même chose que lolotux script , mais sans aucune fourchette à grep , awk ou ps . C'est beaucoup plus rapide!

et comme est l'un des plus pauvres en ce qui concerne la performance, un peu de travail a été fait pour assurez-vous que ce script sera bien exécuté sous , et d'autres. Puis, ( merci à Stéphane Chazelas ,) redevenir 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 citer deux fois "$PROGNAME" ! Voir le commentaire de Stéphane Chazelas :

read FIELD PROGNAME < <(
    perl -ne 'BEGIN{"151910920"="/*/*/../../*/*"} print if /^Name/' /proc/self/status
)
echo $FIELD "$PROGNAME"

Ne tentez pas de echo $PROGNAME sans guillemet double sur un système raisonnable, et être prêt à tuer shell actuel avant!

et une version

comme ceci devient un pas si simple script, le temps s'engage à é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+= if /^VmSwap:\s+(\d+)\s/;
            $nam= 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+= 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 par course avec un de

-c  sort by command name
-p  sort by pid
-m  sort by swap values
by default, output is sorted by status's vmsize
4
répondu F. Hauri 2018-07-29 11:50:41

je suppose que vous pourriez avoir une bonne idée en lançant top et en recherchant des processus actifs en utilisant beaucoup de mémoire. Faire cela programmatiquement est plus difficile - - - il suffit de regarder les débats sans fin sur les heuristiques tueur Linux OOM.

Swapping est une fonction d'avoir plus de mémoire dans l'utilisation active qu'est installé, il est donc généralement difficile de blâmer sur un seul processus. Si c'est un problème, la meilleure solution consiste à installer plus la mémoire, ou faire d'autres changements systémiques.

2
répondu dmckee 2009-01-26 14:44:19

sur MacOSX, vous exécutez aussi la commande top mais vous devez taper "o" puis "vsize" puis entrer.

2
répondu Alexis 2012-01-19 09:31:52

Je ne sais pas de réponse directe quant à savoir comment trouver exactement quel processus utilise l'espace de pagination, cependant, ce lien peut être utile . Un autre bon est ici

aussi, utilisez un bon outil comme htop pour voir quels processus utilisent beaucoup de mémoire et combien de swap global est utilisé.

1
répondu Jean Azzopardi 2009-01-26 14:40:43

iotop est un outil très utile. Il donne des statistiques en direct de l'utilisation d'E/S et de swap par processus / thread. Par défaut, il s'affiche par thread mais vous pouvez faire iotop -P pour obtenir des informations sur chaque processus. Ce n'est pas disponible par défaut. Vous devrez peut-être installer via rpm/apt.

1
répondu sunil 2015-09-01 07:24:52

j'ai adapté un script différent sur le web à ce long-liner:

 { date;for f in /proc/[0-9]*/status; do 
   awk '{k[]=} END { if (k["VmSwap:"]) print k["Pid:"],k["Name:"],k["VmSwap:"];}' $f 2>/dev/null; 
   done | sort -n ; }

que je jette alors dans une cronjob et rediriger la sortie vers un logfile. L'information ici est la même que l'accumulation des entrées Swap: dans le fichier smaps, mais si vous voulez être sûr, vous pouvez utiliser:

{ date;for m in /proc/*/smaps;do 
  awk '/^Swap/ {s+=} END { if (s) print FILENAME,s }' $m 2>/dev/null;
  done | tr -dc ' [0-9]\n' |sort -k 1n; }

la sortie de cette version est en deux colonnes: pid, montant de l'échange. Dans la version ci-dessus, le tr composant. Dans les deux cas, la sortie est triée numériquement par pid.

1
répondu Otheus 2016-03-16 17:15:29

donne les totaux et les pourcentages pour le processus utilisant l'échange

smem -t -p

enter image description here

Source: https://www.cyberciti.biz/faq/linux-which-process-is-using-swap /

1
répondu Soumya Boral 2018-05-30 08:01:04