Bagaimana cara mengetahui proses mana yang menggunakan ruang swap di Linux?

240

Di Linux, bagaimana saya mengetahui proses mana yang lebih banyak menggunakan ruang swap?

Shameem
sumber
30
Jawaban Anda yang diterima salah. Pertimbangkan untuk mengubahnya menjadi jawaban lolotux, yang sebenarnya benar.
jterrace
@ jterrace sudah benar, saya tidak punya ruang swap sebanyak jumlah nilai di kolom SWAP di atas.
akostadinov
1
iotop adalah perintah yang sangat berguna yang akan menampilkan statistik langsung dari io dan menukar penggunaan per proses / utas
sunil
@ jterrace, pertimbangkan untuk menyatakan jawaban siapa yang diterima pada hari itu salah. Enam tahun kemudian, kita semua tidak tahu apakah Anda merujuk pada jawaban David Holm (yang saat ini diterima pada hari ini) atau jawaban lain. (Ya, saya melihat Anda juga mengatakan jawaban David Holm salah, sebagai komentar atas jawabannya ... jadi saya kira Anda mungkin bersungguh-sungguh.)
Don Hatch

Jawaban:

106

Jalankan atas lalu tekan OpEnter. Sekarang proses harus diurutkan berdasarkan penggunaan swap mereka.

Ini adalah pembaruan karena jawaban awal saya tidak memberikan jawaban yang tepat untuk masalah seperti yang ditunjukkan dalam komentar. Dari FAQ htop :

Tidaklah mungkin untuk mendapatkan ukuran persis ruang swap yang digunakan dari suatu proses. Memalsukan informasi ini dengan membuat SWAP = VIRT - RES, tetapi itu bukan metrik yang baik, karena hal-hal lain seperti memori video juga dihitung pada VIRT (misalnya: atas mengatakan proses X saya menggunakan 81M swap, tetapi juga melaporkan sistem saya secara keseluruhan hanya menggunakan 2M swap. Oleh karena itu, saya tidak akan menambahkan kolom Swap serupa ke htop karena saya tidak tahu cara yang dapat diandalkan untuk mendapatkan informasi ini (sebenarnya, saya tidak berpikir itu mungkin untuk mendapatkan nomor yang tepat, karena halaman yang dibagikan).

David Holm
sumber
137
Dari dokumen, kolom SWAP di atas tampaknya hanya menunjukkan berapa banyak swap akan diperlukan jika seluruh proses ditukar, daripada berapa banyak proses sebenarnya ditukar saat ini. Dari apa yang dapat saya katakan setelah pencarian singkat, tidak ada cara untuk menentukan berapa banyak dari setiap proses yang ditukar saat ini. Penulis htop menolak untuk memasukkan kolom seperti itu karena ini (saya memang melihat kolom CNSWAP dan NSWAP, tetapi mereka tampaknya tidak melakukan apa pun pada mesin saya): htop.sourceforge.net/index.php?page=faq
yukondude
6
@yukondude benar, kolom SWAP di atas hanya VIRT - RES dan informasi ini semacam tidak berguna dalam konteks ini. Tidak ada kompensasi untuk misalnya memori bersama dari RAM video yang dipetakan. Juga tidak semua memori mungkin telah dirujuk oleh proses. Dalam hal ini tidak perlu bagi OS untuk membaca biner lengkap dari disk ke memori, dan dengan demikian nilai RES tidak termasuk bagian memori ini.
Bart
Saya akan lebih meningkatkan ini jika saya bisa. Ini menghemat daging saya!
atrain
Syukurlah itulah komentarnya untuk @jterrace :) (walaupun diakui Anda harus membacanya: S ... tidak yakin apa yang dimaksud dengan atrain, saya harap ini yukondude)
AJP
11
Mengenai komentar yang tidak berfungsi lagi: Tampaknya versi teratas yang lebih baru tidak lagi menetapkan 'O' sebagai kunci untuk memilih bidang pengurutan. Kapan menggunakan? Anda dapat melihat nama dan versi program yang sebenarnya, dan menjadi versi terbaru. Ini adalah percabangan oleh Debian, Fedora, dan openSUSE: gitorious.org/procps . Jika Anda masih ingin melakukan pengurutan pada kolom SWAP: Gunakan tombol 'f' untuk melihat bidang, gunakan tombol panah untuk pergi ke SWAP dan gunakan 's' untuk mengatur pengurutan, kemudian 'q'.
Pieter VN
294

Skrip terbaik yang saya temukan ada di halaman ini: http://northernmost.org/blog/find-out-what-is-using-your-swap/

Berikut ini satu varian dari skrip dan tidak diperlukan 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"
lolotux
sumber
Ini salinannya, kalau-kalau tautannya mati: gitorious.org/dolanormisc/scripts/blobs/master/getswapused
TautrimasPajarskas
4
lucu, saya dapatkan Overall swap used: 260672 KB, sementara acara gratis 738932seperti yang digunakan ...
Doncho Gunchev
23
Output yang sama sepuluh kali lebih cepat: for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -nuntuk Debian / RH 6x +, Arch, Ubuntu (RH 5x miliki VmSize) ( sumber ). Seperti @dgunchev itu memang memberikan total swap jauh lebih sedikit daripada free. @Tensibai tidak berfungsi di Arch; awk Anda mungkin kekurangan sesuatu.
tuk0z
1
Silakan lihat skrip versi no fork saya !
F. Hauri
3
Penulis memiliki posting tindak lanjut tentang cara melakukannya menggunakan top: northernmost.org/blog/swap-usage-5-years-later
Jack Valmadre
53

Berikut varian lain dari skrip, tetapi dimaksudkan untuk memberikan hasil yang lebih mudah dibaca (Anda perlu menjalankan ini sebagai root untuk mendapatkan hasil yang tepat):

#!/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}/";
j3nda
sumber
2
Skrip yang sangat bagus. Ini memberikan informasi yang sama dengan lolotux, tetapi dengan cara yang lebih baik dibaca.
Philipp Wendler
Output luar biasa. Terima kasih.
Brian Cline
2
Satu-satunya hal yang saya ubah adalah menggunakan argsalih-alih commdalam psperintah karena saya memiliki banyak proses dengan nama yang sama tetapi argumen yang berbeda (banyak proses python gunicorn). Yakni:ps -p $PID -o args --no-headers
mgalg
1
Catatan pinggir grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'bisa disederhanakan sebagaiawk ' /VmSwap/ { print $2 }'
Tensibai
12

Saya memang melihat utas ini agak lama, tetapi jika Anda kebetulan menemukannya, seperti yang baru saja saya lakukan, jawaban lain adalah: gunakan smem.

Berikut ini tautan yang memberi tahu Anda cara menginstalnya dan cara menggunakannya:

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

Tom
sumber
Yang ini bagus. Berikut versi yang diadaptasi dari artikel itu untuk menunjukkan procs yang diurutkan berdasarkan penggunaan swap dengan PID ditambahkan: $ untuk file dalam / proc / * / status; do awk '/ ^ Pid | VmSwap | Name / {printf $ 2 "" $ 3} END {print ""}' $ file; selesai | sort -k 3 -n -r | kurang
Stan Brajewski
Anda harus glob / proc / [1-9] * / Status untuk mengecualikan beberapa entri khusus / proc, dan Anda dapat menggabungkan args semacam sebagai -rnk3
dland
10

Tidak sepenuhnya jelas apakah maksud Anda ingin menemukan proses yang memiliki sebagian besar halaman berganti atau proses yang menyebabkan sebagian besar halaman diganti.

Untuk yang pertama Anda dapat menjalankan topdan memesan dengan menukar (tekan 'Op'), untuk yang terakhir Anda dapat menjalankan vmstatdan mencari entri yang tidak nol untuk 'jadi'.

Ronny Vindenes
sumber
6

Perintah teratas juga berisi bidang untuk menampilkan jumlah kesalahan halaman untuk suatu proses. Proses dengan kesalahan halaman maksimum akan menjadi proses yang paling banyak bertukar. Untuk daemon yang berjalan lama, bisa jadi mereka mengalami banyak kesalahan halaman di awal dan jumlahnya tidak bertambah di kemudian hari. Jadi kita perlu mengamati apakah kesalahan halaman meningkat.

Amol Kulkarni
sumber
6

Varian skrip lain yang menghindari loop di 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
  }'

Penggunaan standar adalah script.shuntuk mendapatkan penggunaan per program dengan urutan acak (ke bagaimana awkmenyimpan hash-nya) atau script.sh 1untuk mengurutkan output dengan pid.

Saya harap saya sudah cukup berkomentar kode untuk mengetahui apa fungsinya.

Tensibai
sumber
1
Catatan yang bashmemperluas direktori dengan cara diurutkan (leksikal, bukan numerik). Urutan acak adalah bagaimana awkmenyimpan array (tabel hash) dan bagaimana for p in pnamemengambilnya.
Stephane Chazelas
@StephaneChazelas Yah, itu bahkan tidak leksikal, itu semacam kode ascii (seperti yang /proc/1/statusmuncul setelah /proc/1992/statusdan /memiliki kode ascii di atas kode asci 9. Ini memberikan "urutan acak" tampilan dan nuansa juga. Saya setuju dengan tabel hash awk , Saya mengambil jalan pintas di sini. Jangan ragu untuk mengedit jawaban untuk menjaga atribusi dalam riwayat edit.
Tensibai
1
/proc/1/statustidak akan muncul setelah /proc/1992/statusdi C locale di mana pesanan didasarkan pada nilai byte. Itu di lokal Anda (atau di saya en_GB.UTF-8di sistem GNU), karena /ada diabaikan dalam contoh pertama dalam algoritma pemeriksaan (dan ssetelahnya 9). Bandingkan printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sortdengan printf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort. Di lokal selain C, urutan sortir umumnya tidak didasarkan pada nilai byte.
Stephane Chazelas
@StephaneChazelas Poin yang bagus, meskipun tidak tentang lokal. Sekali lagi merasa bebas untuk mengedit untuk menambah presisi sehingga kredit akan menjadi milik Anda (setidaknya di edit riwayat).
Tensibai
2
Selesai Jawaban ini jauh lebih baik daripada yang paling banyak dipilih di sini. Itu memang pantas mendapat lebih banyak upvotes. Itu dan jawaban lain di sini dibahas di Mengapa menggunakan shell loop untuk memproses teks dianggap praktik buruk? itulah yang membawaku ke sini.
Stephane Chazelas
6

Namun dua varian lagi:

Karena topatau htoptidak dapat diinstal pada sistem kecil, penjelajahan /proctetap dapat dilakukan.

Bahkan pada sistem kecil, Anda akan menemukan shell...

SEBUAH varian! (Tidak hanya bash)

Ini persis sama dengan script lolotux , tetapi tanpa garpu untuk grep, awkatau ps. Ini jauh lebih cepat!

Dan sebagai adalah salah satu yang termiskin mengenai kinerja, sedikit pekerjaan telah dilakukan untuk memastikan skrip ini akan berjalan dengan baik , dan beberapa lainnya. Kemudian, ( terima kasih kepada Stéphane Chazelas ,) menjadi jauh lebih cepat lagi!

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

Jangan lupa untuk menggandakan penawaran "$PROGNAME"! Lihat komentar Stéphane Chazelas :

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

Jangan mencoba echo $PROGNAMEtanpa tanda kutip ganda pada sistem yang masuk akal, dan bersiaplah untuk membunuh shell saat ini sebelumnya!

Dan a Versi: kapan

Karena ini menjadi skrip yang tidak begitu sederhana , waktu berkomitmen untuk menulis alat khusus dengan menggunakan bahasa yang lebih efisien.

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

bisa dengan menjalankannya dengan

-c  sort by command name
-p  sort by pid
-m  sort by swap values
by default, output is sorted by status's vmsize
F. Hauri
sumber
Ini mengasumsikan nama proses tidak mengandung spasi, tab :,, garis miring terbalik, karakter pengganti atau karakter kontrol.
Stephane Chazelas
@StephaneChazelas Terima kasih! Saya telah menambahkan [1-9]sebelumnya *untuk menghitung hanya jalur bernomor (tidak self, tidak thread-self)
F. Hauri
1
Sintaks dikenal, tetapi nama proses tidak. Setidaknya kutip variabel Anda . (Bagaimanapun, skrip Anda jauh lebih buruk daripada loloxux ').
Stephane Chazelas
1
Nama proses di Linux dapat berisi nilai byte apa pun kecuali 0 tetapi panjangnya dibatasi hingga 15 byte. The Namemasuk dalam /proc/*/statusmengkodekan beberapa nilai-nilai byte. Coba misalnya perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/status. Karena sangat singkat, kerusakan yang dapat dilakukan dengan hal-hal seperti perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/statusterbatas ketika Anda lupa mengutip variabel Anda.
Stephane Chazelas
1
Ini (setidaknya versi perl yang saya hanya mencoba) adalah sangat cepat dari jawaban lainnya.
David Gardner
5

Saya mengadaptasi skrip yang berbeda di web dengan one-liner panjang ini:

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

Yang kemudian saya lempar ke cronjob dan mengarahkan output ke logfile. Informasi di sini sama dengan mengumpulkan Swap:entri dalam file smaps, tetapi jika Anda ingin memastikan, Anda dapat menggunakan:

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

Output dari versi ini adalah dalam dua kolom: pid, jumlah swap. Dalam versi di atas, trstrip komponen non-numerik. Dalam kedua kasus, output diurutkan secara numerik dengan pid.

Otheus
sumber
2
Ini bagus, tapi yang pertama mengurutkan dengan pid naik (sort -n). Penggunaan yang lebih baik adalah mengurutkannya dengan menukar penggunaan dalam urutan menurun (yang paling banyak digunakan di depan daftar). Untuk mengubahnya, "sort -n" menjadi "sort -n -k 3 -r"
Stan Brajewski
3

Di MacOSX, Anda menjalankan perintah teratas juga tetapi harus mengetik "o" lalu "vsize" lalu ENTER.

Alexis
sumber
2

Saya kira Anda bisa menebak dengan menjalankan topdan mencari proses aktif menggunakan banyak memori. Melakukan hal ini secara terprogram lebih sulit --- lihat saja debat tak berujung tentang heuristik pembunuh Linux OOM.

Bertukar adalah fungsi memiliki lebih banyak memori dalam penggunaan aktif daripada yang diinstal, jadi biasanya sulit untuk menyalahkannya pada satu proses tunggal. Jika ini merupakan masalah yang berkelanjutan, solusi terbaik adalah menginstal lebih banyak memori, atau membuat perubahan sistemik lainnya.

dmckee --- mantan kucing moderator
sumber
1

Saya tidak tahu jawaban langsung bagaimana menemukan proses apa yang menggunakan ruang swap, namun tautan ini mungkin membantu . Satu lagi yang bagus ada di sini

Juga, gunakan alat yang bagus seperti htop untuk melihat proses mana yang menggunakan banyak memori dan berapa banyak swap yang digunakan secara keseluruhan.

Jean Azzopardi
sumber
1

iotopadalah alat yang sangat berguna. Ini memberikan statistik langsung I / O dan menukar penggunaan per proses / utas. Secara default ini menunjukkan per utas tetapi Anda bisa lakukan iotop -Puntuk mendapatkan per info proses. Ini tidak tersedia secara default. Anda mungkin harus menginstal melalui rpm / apt.

sunil
sumber
1

Berikut adalah versi yang menampilkan sama dengan skrip oleh @loolotux, tetapi jauh lebih cepat (sementara kurang dapat dibaca). Pengulangan itu membutuhkan waktu sekitar 10 detik pada mesin saya, versi saya membutuhkan waktu 0,019 detik, yang penting bagi saya karena saya ingin membuatnya menjadi halaman 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
Dmitry z
sumber
1

Sejak tahun 2015 kernel patch yang menambahkan SwapPss( https://lore.kernel.org/patchwork/patch/570506/ ) orang akhirnya bisa mendapatkan jumlah swap proporsional yang berarti bahwa jika suatu proses telah banyak bertukar dan kemudian bercabang, kedua proses bercabang dua akan dilaporkan menukar masing-masing 50%. Dan jika salah satu dari itu bercabang, setiap proses dihitung 33% dari halaman yang ditukar jadi jika Anda menghitung semua penggunaan swap bersama, Anda mendapatkan penggunaan swap nyata alih-alih nilai dikalikan dengan jumlah proses.

Pendeknya:

(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)

Kolom pertama adalah pid, kolom kedua adalah swap penggunaan di KiB dan sisanya baris perintah dieksekusi. Jumlah swap identik diurutkan berdasarkan pid.

Di atas dapat memancarkan garis seperti

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

yang berarti proses dengan pid 15407 berakhir antara melihatnya dalam daftar untuk /proc/dan membaca smapsfile proses . Jika itu penting bagi Anda, cukup tambahkan 2>/dev/nullsampai akhir. Perhatikan bahwa Anda juga berpotensi kehilangan diagnostik lainnya.

Dalam contoh kasus dunia nyata, ini mengubah alat lain yang melaporkan ~ 40 MB penggunaan swap untuk setiap anak apache yang berjalan pada satu server ke penggunaan aktual antara 7-3630 KB yang benar-benar digunakan per anak.

Mikko Rantalainen
sumber