Di Linux, bagaimana saya mengetahui proses mana yang lebih banyak menggunakan ruang swap?
Di Linux, bagaimana saya mengetahui proses mana yang lebih banyak menggunakan ruang swap?
Jawaban:
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).
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"
Overall swap used: 260672 KB
, sementara acara gratis 738932
seperti yang digunakan ...
for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -n
untuk 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.
top
: northernmost.org/blog/swap-usage-5-years-later
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}/";
args
alih-alih comm
dalam ps
perintah 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
grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'
bisa disederhanakan sebagaiawk ' /VmSwap/ { print $2 }'
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/
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 top
dan memesan dengan menukar (tekan 'Op'), untuk yang terakhir Anda dapat menjalankan vmstat
dan mencari entri yang tidak nol untuk 'jadi'.
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.
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.sh
untuk mendapatkan penggunaan per program dengan urutan acak (ke bagaimana awk
menyimpan hash-nya) atau script.sh 1
untuk mengurutkan output dengan pid.
Saya harap saya sudah cukup berkomentar kode untuk mengetahui apa fungsinya.
bash
memperluas direktori dengan cara diurutkan (leksikal, bukan numerik). Urutan acak adalah bagaimana awk
menyimpan array (tabel hash) dan bagaimana for p in pname
mengambilnya.
/proc/1/status
muncul setelah /proc/1992/status
dan /
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.
/proc/1/status
tidak akan muncul setelah /proc/1992/status
di C locale di mana pesanan didasarkan pada nilai byte. Itu di lokal Anda (atau di saya en_GB.UTF-8
di sistem GNU), karena /
ada diabaikan dalam contoh pertama dalam algoritma pemeriksaan (dan s
setelahnya 9
). Bandingkan printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sort
dengan printf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort
. Di lokal selain C
, urutan sortir umumnya tidak didasarkan pada nilai byte.
Karena top
atau htop
tidak dapat diinstal pada sistem kecil, penjelajahan /proc
tetap dapat dilakukan.
Bahkan pada sistem kecil, Anda akan menemukan shell
...
Ini persis sama dengan script lolotux , tetapi tanpa garpu untuk grep
, awk
atau ps
. Ini jauh lebih cepat!
Dan sebagai pesta adalah salah satu yang termiskin kulit mengenai kinerja, sedikit pekerjaan telah dilakukan untuk memastikan skrip ini akan berjalan dengan baik berlari, busyboxdan 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 $PROGNAME
tanpa tanda kutip ganda pada sistem yang masuk akal, dan bersiaplah untuk membunuh shell saat ini sebelumnya!
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
:
,, garis miring terbalik, karakter pengganti atau karakter kontrol.
[1-9]
sebelumnya *
untuk menghitung hanya jalur bernomor (tidak self
, tidak thread-self
)
Name
masuk dalam /proc/*/status
mengkodekan 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/status
terbatas ketika Anda lupa mengutip variabel Anda.
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, tr
strip komponen non-numerik. Dalam kedua kasus, output diurutkan secara numerik dengan pid.
Saya kira Anda bisa menebak dengan menjalankan top
dan 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.
Memberikan total dan persentase untuk proses menggunakan swap
smem -t -p
Sumber: https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
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.
iotop
adalah 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 -P
untuk mendapatkan per info proses. Ini tidak tersedia secara default. Anda mungkin harus menginstal melalui rpm / apt.
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
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 smaps
file proses . Jika itu penting bagi Anda, cukup tambahkan 2>/dev/null
sampai 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.