Wie finde ich heraus, welche Prozesse unter Linux Swap Space verwenden?


240

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


30
Ihre akzeptierte Antwort ist falsch. Erwägen Sie, es in die Antwort von lolotux zu ändern, die tatsächlich richtig ist.
Jterrace

@jterrace ist korrekt, ich habe nicht so viel Swap-Speicherplatz wie die Summe der Werte in der SWAP-Spalte oben.
Akostadinov

1
iotop ist ein sehr nützlicher Befehl, der Live-Statistiken der Io- und Swap-Nutzung pro Prozess / Thread
anzeigt

@jterrace, sollte unter Angabe deren akzeptierte-Antwort-of-the-Tag falsch ist. Sechs Jahre später haben wir alle keine Ahnung, ob Sie sich auf die Antwort von David Holm (die derzeit akzeptierte bis heute) oder eine andere Antwort bezogen haben. (Nun, ich sehe, Sie haben auch gesagt, dass David Holms Antwort falsch ist, als Kommentar zu seiner Antwort ... also haben Sie wahrscheinlich seine gemeint.)
Don Hatch

Antworten:


106

Oben laufen lassen und dann drücken OpEnter. Jetzt sollten Prozesse nach ihrer Swap-Verwendung sortiert werden.

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

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


137
Aus den Dokumenten geht hervor, dass die SWAP-Spalte oben nur zeigt, wie viel Swap erforderlich wäre, wenn der gesamte Prozess ausgelagert würde, und nicht, wie viel des Prozesses derzeit tatsächlich ausgetauscht wird. Nach dem, was ich nach einer kurzen Suche feststellen kann, kann derzeit nicht festgestellt werden, wie viel von jedem Prozess ausgetauscht wird. Der Autor von htop weigert sich aus diesem Grund, eine solche Spalte einzufügen (ich sehe CNSWAP- und NSWAP-Spalten, aber sie scheinen auf meinem Computer nichts zu tun): htop.sourceforge.net/index.php?page=faq
Yukondude

6
@yukondude ist richtig, die SWAP-Spalte oben ist nur VIRT - RES und diese Informationen sind in diesem Zusammenhang irgendwie nutzlos. Es gibt keine Kompensation für z. B. gemeinsam genutzten Speicher des zugeordneten Video-RAM. Möglicherweise wurde noch nicht der gesamte Speicher vom Prozess referenziert. In diesem Fall muss das Betriebssystem nicht die gesamte Binärdatei von der Festplatte in den Speicher lesen. Daher enthält der Wert von RES diesen Teil des Speichers nicht.
Bart

Ich würde dies mehr unterstützen, wenn ich könnte. Das spart meinen Speck!
Atrain

Zum Glück sind das die Kommentare für @jterrace :) (obwohl man sie zugegebenermaßen lesen muss: S ... nicht sicher, worauf sich atrain bezieht, ich hoffe es ist yukondude)
AJP

11
In Bezug auf den Kommentar, der nicht mehr funktioniert: In neueren Versionen von top ist 'O' anscheinend nicht mehr als Schlüssel für die Auswahl der Sortierfelder festgelegt. Bei Verwendung des? Mit der Taste können Sie den tatsächlichen Programmnamen und die aktuelle Version sehen, wobei procps-ng die neueste Version ist. Dies ist eine Gabelung von Debian, Fedora und openSUSE: gitorious.org/procps . Wenn Sie dennoch eine Sortierung in der SWAP-Spalte durchführen möchten: Verwenden Sie die Taste 'f', um die Felder anzuzeigen, verwenden Sie die Pfeiltasten, um zu SWAP zu wechseln, und verwenden Sie 's', um die Sortierung festzulegen, und dann 'q'.
Pieter VN

294

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 und kein Root erforderlich:

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


4
lustig aber, ich bekomme Overall swap used: 260672 KB, während kostenlose Shows 738932wie verwendet ...
Doncho Gunchev

23
Gleiche Ausgabe zehnmal schneller: for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -nfür Debian / RH 6x +, Arch, Ubuntu (RH 5x hat VmSize) ( Quelle ). Wie bei @dgunchev gibt es viel weniger Total Swap als free. @Tensibai funktioniert nicht bei Arch; Ihrem awk kann etwas fehlen.
Tuk0z

1
Bitte schauen Sie sich meine No-Fork-Version dieses Skripts an!
F. Hauri

3
Der Autor hat einen Follow-up-Beitrag darüber, wie es geht mit top: northmost.org/blog/swap-usage-5-years-later
Jack Valmadre

53

Hier ist eine andere Variante des Skripts, die jedoch eine besser lesbare Ausgabe ermöglichen 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}/";

2
Sehr schönes Skript. Es gibt die gleichen Informationen wie die von lolotux, jedoch besser lesbar.
Philipp Wendler

Hervorragende Leistung. Vielen Dank.
Brian Cline

2
Das einzige , was ich verändert wurde mit argsstatt commin dem psBefehl , da ich viele Prozesse mit dem gleichen Namen , aber unterschiedlichen Argumenten (eine Reihe von Python gunicorn Prozessen) habe. ps -p $PID -o args --no-headers
Dh

1
Randnotiz das grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'könnte vereinfacht werden alsawk ' /VmSwap/ { print $2 }'
Tensibai

12

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: Verwenden Sie smem.

Hier ist ein Link, der Ihnen erklärt, wie Sie es installieren und wie Sie es verwenden:

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


Dieses ist gut. Hier ist eine angepasste Version aus diesem Artikel, um die nach Swap-Verwendung sortierten Prozesse mit hinzugefügter PID anzuzeigen: $ für Datei in / proc / * / status; do awk '/ ^ Pid | VmSwap | Name / {printf $ 2 "" $ 3} END {print ""}' $ file; erledigt | sort -k 3 -n -r | weniger
Stan Brajewski

Sie sollten glob / proc / [1-9] * / status verwenden, um einige spezielle / proc-Einträge auszuschließen, und Sie können die Sortierargumente als -rnk3
dland

10

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

Zum ersten können Sie topper Swap ausführen und bestellen (drücken Sie 'Op'), zum letzteren können Sie vmstatEinträge ungleich Null für 'so' ausführen und suchen.


6

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


6

Eine andere Skriptvariante, die die Schleife in der 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
  }'

Die Standardverwendung besteht script.shdarin, die Verwendung pro Programm in zufälliger Reihenfolge abzurufen (bis hin zur awkSpeicherung der Hashes) oder script.sh 1die Ausgabe nach PID zu sortieren.

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


1
Beachten Sie, dass bashdie Verzeichnisse sortiert erweitert werden (lexikalisch, nicht numerisch). Die zufällige Reihenfolge hängt davon ab, wie awkdie Arrays gespeichert werden (Hash-Tabelle) und wie sie for p in pnameabgerufen werden.
Stephane Chazelas

@StephaneChazelas Nun, das ist nicht einmal lexikalisch, das ist eine ASCII-Codesortierung (wie es später /proc/1/statuskommt /proc/1992/statusund dass der /ASCII-Code über dem 9-ASCII-Code liegt. Dies ergibt auch ein "zufälliges" Look & Feel. Ich stimme der awk-Hash-Tabelle zu Ich habe hier eine Verknüpfung genommen. Sie können die Antwort jederzeit bearbeiten, um die Zuordnung im Bearbeitungsverlauf
beizubehalten

1
/proc/1/statuswürde nicht /proc/1992/statusim Gebietsschema C kommen, in dem die Reihenfolge auf dem Bytewert basiert. Dies geschieht in Ihrem Gebietsschema (oder in meinem en_GB.UTF-8auf einem GNU-System), da /es in erster Linie im Kollatierungsalgorithmus ignoriert wird (und danach ssortiert 9). Vergleiche printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sortmit printf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort. In anderen Gebietsschemas als basiert Cdie Sortierreihenfolge im Allgemeinen nicht auf dem Bytewert.
Stephane Chazelas

@StephaneChazelas Netter Punkt, aber nicht über das Gebietsschema. Sie können es auch hier bearbeiten, um die Genauigkeit zu erhöhen, sodass die Credits Ihnen gehören (zumindest bei der Bearbeitung des Verlaufs).
Tensibai

2
Getan. Diese Antwort ist viel besser als die am meisten gewählte hier. Es verdient mehr Gegenstimmen. Diese und andere Antworten wurden hier unter Warum wird die Verwendung einer Shell-Schleife zur Verarbeitung von Text als schlechte Praxis angesehen? Das hat mich hierher gebracht.
Stephane Chazelas

6

Noch zwei weitere Varianten:

Da das Surfen auf kleinen Systemen nicht möglich ist topoder htopnicht /procmöglich ist, bleibt das Surfen immer möglich.

Selbst auf kleinen Systemen finden Sie eine shell...

EIN Variante! (Nicht nur Bash)

Das ist genau das gleiche als lolotux Skript , aber ohne Gabel grep, awkoder ps. Das geht viel schneller!

Und wie ist einer der ärmsten In Bezug auf die Leistung wurde ein wenig Arbeit geleistet, um sicherzustellen, dass dieses Skript gut funktioniert , und einige andere. Dann ( dank Stéphane Chazelas ) 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, doppelt zu zitieren "$PROGNAME"! Siehe Stéphane Chazelas 'Kommentar :

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

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

Und ein Ausführung

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 laufen

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

Es wird davon ausgegangen, dass Prozessnamen kein Leerzeichen, Tabulator :, Backslash, Platzhalter oder Steuerzeichen enthalten.
Stephane Chazelas

@StephaneChazelas Danke! Ich habe [1-9]zuvor hinzugefügt, *um nur nummerierte Pfade zu zählen (nein self, noch thread-self)
F. Hauri

1
Die Syntax ist bekannt, die Prozessnamen jedoch nicht. Zitieren Sie zumindest Ihre Variablen . (In jedem Fall ist Ihr Skript viel weniger schlecht als loloxux ').
Stephane Chazelas

1
Prozessnamen unter Linux können einen beliebigen Bytewert außer 0 enthalten, sind jedoch auf eine Länge von 15 Byte begrenzt. Der NameEintrag in /proc/*/statuscodiert einige dieser Bytewerte. Versuchen Sie es zum Beispiel perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/status. Weil es so kurz ist, ist der Schaden, der mit Dingen wie angerichtet werden kann, perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/statusbegrenzt, wenn Sie vergessen, Ihre Variablen anzugeben.
Stephane Chazelas

1
Dies (zumindest die Perl-Version, die ich gerade ausprobiert habe) ist enorm schneller als die anderen Antworten.
David Gardner

5

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

Was ich dann in einen Cronjob werfe und die Ausgabe in eine Protokolldatei umleitung. Die Informationen hier sind die gleichen wie beim Sammeln der Swap:Einträge in der Smaps-Datei. Wenn Sie jedoch 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 werden trdie nicht numerischen Komponenten entfernt. In beiden Fällen wird die Ausgabe numerisch nach pid sortiert.


2
Das ist gut, aber der erste sortiert nach aufsteigender PID (sort -n). Die bessere Verwendung besteht darin, sie nach Swap-Verwendung in absteigender Reihenfolge sortieren zu lassen (die am häufigsten verwendete vor der Liste). Um es zu bekommen, ändern Sie "sort -n" in "sort -n -k 3 -r"
Stan Brajewski

3

Unter MacOSX führen Sie auch den Befehl top aus, müssen jedoch "o", dann "vsize" und dann ENTER eingeben.


2

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

Das Austauschen ist eine Funktion, bei der mehr Speicher aktiv genutzt wird als installiert ist. Daher ist es normalerweise schwierig, einen einzelnen Prozess dafür verantwortlich zu machen. Wenn es sich um ein anhaltendes Problem handelt, besteht die beste Lösung darin, mehr Speicher zu installieren oder andere systemische Änderungen vorzunehmen.



1

Ich kenne keine direkte Antwort darauf, wie ich genau herausfinden kann, welcher Prozess den Swap Space verwendet. Dieser Link kann jedoch hilfreich sein . Ein weiterer guter ist hier

Verwenden Sie außerdem ein gutes Tool wie htop, um festzustellen, welche Prozesse viel Speicher belegen und wie viel Swap insgesamt verwendet wird.


1

iotopist ein sehr nützliches Werkzeug. Es gibt Live-Statistiken der E / A- und Swap-Nutzung pro Prozess / Thread. Standardmäßig wird pro Thread angezeigt, Sie können jedoch iotop -Ppro Prozess Informationen abrufen. Dies ist standardmäßig nicht verfügbar. Möglicherweise müssen Sie über rpm / apt installieren.


1

Hier ist eine Version, die das gleiche wie das Skript von @loolotux ausgibt, aber viel schneller ist (obwohl sie weniger lesbar ist). Diese Schleife dauert auf meinem Computer ungefähr 10 Sekunden, meine Version dauert 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

1

Seit dem Kernel-Patch des Jahres 2015, der hinzufügt SwapPss( https://lore.kernel.org/patchwork/patch/570506/ ), kann man endlich eine proportionale Swap-Anzahl erhalten, was bedeutet, dass beide Prozesse gegabelt wurden, wenn ein Prozess viel getauscht und dann gegabelt wurde Es wird berichtet, dass jeweils 50% getauscht werden. Und wenn einer der beiden sich teilt, wird jeder Prozess mit 33% der ausgetauschten Seiten gezählt. Wenn Sie also alle diese Auslagerungsnutzungen zusammenzählen, erhalten Sie eine echte Auslagerungsnutzung anstelle des Werts multipliziert mit der Prozessanzahl.

Zusamenfassend:

(cd /proc; for pid in [0-9]*; do printf "%5s %6s %s\n" "$pid" "$(awk 'BEGIN{sum=0} /SwapPss:/{sum+=$2} END{print sum}' $pid/smaps)" "$(cat $pid/comm)"; done | sort -k2n,2 -k1n,1)

Die erste Spalte ist pid, die zweite Spalte ist die Swap-Verwendung in KiB und der Rest der Zeile ist der Befehl, der ausgeführt wird. Identische Swap-Zählungen werden nach PID sortiert.

Oben können Zeilen wie

awk: cmd. line:1: fatal: cannot open file `15407/smaps' for reading (No such file or directory)

Dies bedeutet einfach, dass der Prozess mit pid 15407 zwischen dem Anzeigen in der Liste für /proc/und dem Lesen der Prozessdatei beendet wurde smaps. Wenn Ihnen das wichtig ist, fügen Sie es einfach 2>/dev/nullam Ende hinzu. Beachten Sie, dass Sie möglicherweise auch andere mögliche Diagnosen verlieren.

Im realen Beispielfall ändert dies andere Tools, die eine Swap-Nutzung von ~ 40 MB für jedes auf einem Server ausgeführte Apache-Kind melden, in eine tatsächliche Nutzung von 7 bis 3630 KB, die tatsächlich pro Kind verwendet wird.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.