it-swarm.com.de

Wie kann man herausfinden, welche Prozesse unter Linux Swap Space verwenden?

Wie finde ich unter Linux heraus, welcher Prozess den Swap Space mehr nutzt?

230
Shameem

Führen Sie top aus und drücken Sie dann OpEnter. Jetzt sollten Prozesse nach ihrer Auslagerungsnutzung sortiert werden.

Hier ist ein Update, da meine ursprüngliche Antwort keine genaue Antwort auf das in den Kommentaren erwähnte Problem liefert. Aus dem htop FAQ :

Es ist nicht möglich, die genaue Größe des verwendeten Swap Space eines Prozesses abzurufen. Top fälscht diese Informationen mit SWAP = VIRT - RES, aber das ist keine gute Metrik, da auch andere Dinge wie der Videospeicher auf VIRT zählen (zum Beispiel: top sagt, mein X - Prozess verwendet 81 MB Swap, aber auch meldet, dass mein System insgesamt nur 2M Swap verwendet. Daher werde ich keine ähnliche Swap-Spalte zu htop hinzufügen, da ich keinen zuverlässigen Weg kenne, um diese Informationen zu erhalten (eigentlich glaube ich nicht, dass es möglich ist, diese Informationen zu erhalten) eine genaue Zahl, wegen gemeinsam genutzter Seiten).

102
David Holm

Das beste Skript, das ich gefunden habe, befindet sich auf dieser Seite: http://northernmost.org/blog/find-out-what-is-using-your-swap/

Hier ist eine Variante des Skripts ohne Root:

#!/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"
286
lolotux

Hier ist eine andere Variante des Skripts, die jedoch eine besser lesbare Ausgabe liefern soll (Sie müssen diese als root ausführen, um genaue Ergebnisse zu erhalten):

#!/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}/";
53
j3nda

Es ist nicht ganz klar, ob Sie den Prozess finden möchten, bei dem die meisten Seiten ausgelagert wurden, oder ob der Prozess, bei dem die meisten Seiten ausgelagert wurden.

Zum einen können Sie top ausführen und per Swap bestellen (drücken Sie 'Op'), zum anderen können Sie vmstat ausführen und nach Einträgen suchen, die nicht Null sind, um 'so' zu erhalten.

10
Ronny Vindenes

Ich habe bemerkt, dass dieser Thread ziemlich alt ist, aber wenn Sie zufällig darauf stoßen, wie ich es gerade getan habe, lautet eine andere Antwort: use smem.

Hier ist ein Link, der Ihnen erklärt, wie man es installiert und wie man es benutzt:

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

10
Tom

Eine weitere Skriptvariante, die die Schleife in Shell vermeidet:

#!/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
  }'

Standardgebrauch ist script.sh, um die Verwendung pro Programm in zufälliger Reihenfolge zu erhalten (bis zu dem, wie awk seine Hashes speichert) oder script.sh 1 um die Ausgabe nach pid zu sortieren.

Ich hoffe, ich habe den Code genug kommentiert, um zu sagen, was er tut.

6
Tensibai

Der Befehl top enthält auch ein Feld, in dem die Anzahl der Seitenfehler für einen Prozess angezeigt wird. Der Prozess mit den meisten Seitenfehlern ist der Prozess, der am häufigsten ausgetauscht wird. Bei lang laufenden Daemons kann es vorkommen, dass sie am Anfang eine große Anzahl von Seitenfehlern aufweisen und diese Anzahl später nicht ansteigt. Wir müssen also beobachten, ob die Seitenfehler zunehmen.

6
Amol Kulkarni

Noch zwei weitere Varianten:

Eine Shell Variante! (Nicht nur Bash)

Dies ist genau dasselbe wie Lolotux-Skript , jedoch ohne Verzweigung auf grep, awk oder ps. Das geht viel schneller!

Und da bash in Bezug auf die Leistung eines der schlechtesten Shell ist, wurde ein wenig Arbeit geleistet, um sicherzustellen, dass dieses Skript auch unter dash , - läuft. busybox und einige andere. Dann ( danke an Stéphane Chazelas ,) werde wieder viel schneller!

#!/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

Vergessen Sie nicht, "$PROGNAME" In Anführungszeichen zu setzen! Siehe Kommentar von Stéphane Chazelas :

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

Versuchen Sie nicht echo $PROGNAME Ohne Anführungszeichen auf einem vernünftigen System und seien Sie bereit, die aktuelle Shell vorher zu töten!

Und eine Perl Version

Da dies ein nicht so einfaches Skript wird, wird es Zeit, ein spezielles Tool mit einer effizienteren Sprache zu schreiben.

#!/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;

könnte mit einem von ihnen durchrennen

-c  sort by command name
-p  sort by pid
-m  sort by swap values
by default, output is sorted by status's vmsize
5
F. Hauri

Ich habe ein anderes Skript im Web an diesen langen Einzeiler angepasst:

 { 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 ; }

Den werfe ich dann in einen Cronjob und leite die Ausgabe in eine Logdatei um. Die Informationen hier sind die gleichen wie das Sammeln des Swap: Einträge in der smaps-Datei, aber wenn Sie sicher sein möchten, können Sie Folgendes verwenden:

{ 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; }

Die Ausgabe dieser Version erfolgt in zwei Spalten: pid, Swap-Betrag. In der obigen Version entfernt das tr die nicht numerischen Komponenten. In beiden Fällen wird die Ausgabe numerisch nach pid sortiert.

4
Otheus

Unter MacOSX führen Sie ebenfalls den Befehl top aus, müssen jedoch "o", dann "vsize" und anschließend die EINGABETASTE eingeben.

3
Alexis

Ich nehme an, Sie könnten eine gute Vermutung anstellen, indem Sie top ausführen und mit viel Speicher nach aktiven Prozessen suchen. Dies programmatisch zu tun ist schwieriger - schauen Sie sich nur die endlosen Debatten über die Linux OOM Killer-Heuristik an.

Das Austauschen ist eine Funktion, bei der mehr Speicher in aktiv verwendet wird als installiert ist. Daher ist es normalerweise schwierig, einen einzelnen Prozess dafür verantwortlich zu machen. Wenn das Problem weiterhin besteht, ist es am besten, mehr Arbeitsspeicher zu installieren oder andere systembedingte Änderungen vorzunehmen.

2
dmckee

Gibt Summen und Prozentsätze für den Prozess mit Swap an

smem -t -p

enter image description here

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

1
Soumya Boral

iotop ist ein sehr nützliches Werkzeug. Es gibt Live-Statistiken der I/O- und Swap-Nutzung pro Prozess/Thread. Standardmäßig wird pro Thread angezeigt, aber Sie können iotop -P um pro Prozess Informationen zu erhalten. Dies ist standardmäßig nicht verfügbar. Möglicherweise müssen Sie über rpm/apt installieren.

1
sunil

Ich kenne keine direkte Antwort, wie ich genau finde, welcher Prozess den Swap Space nutzt. Dieser Link könnte jedoch hilfreich sein. Ein anderer guter ist hier

Verwenden Sie auch ein gutes Tool wie htop, um festzustellen, welche Prozesse viel Arbeitsspeicher belegen und wie viel Swap insgesamt verwendet wird.

1
Jean Azzopardi

Hier ist eine Version, die dasselbe ausgibt wie das Skript von @loolotux, jedoch viel schneller ist (obwohl weniger lesbar). Diese Schleife dauert auf meinem Computer ungefähr 10 Sekunden, meine Version 0,019 Sekunden, was mir wichtig war, weil ich daraus eine CGI-Seite machen wollte.

    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
0
Dmitry z