Linux altında, takas alanını hangi işlemin daha fazla kullandığını nasıl öğrenebilirim?
Linux altında, takas alanını hangi işlemin daha fazla kullandığını nasıl öğrenebilirim?
Yanıtlar:
Üst kısmı çalıştırın ve düğmesine basın OpEnter. Artık işlemler takas kullanımlarına göre sıralanmalıdır.
İşte benim orijinal cevabım yorumlarda belirtildiği gibi soruna kesin bir cevap vermediği için bir güncelleme. Gönderen htop SSS :
Bir işlemin kullanılan takas alanının tam boyutunu elde etmek mümkün değildir. Top bu bilgileri SWAP = VIRT - RES yaparak sahte yapar, ancak bu iyi bir metrik değildir, çünkü video belleği gibi diğer şeyler de VIRT'de sayılır (örneğin: top X işlemimin 81M takas kullandığını söylüyor, ancak aynı zamanda sistemimi bir bütün olarak yalnızca 2M takas kullandığını bildiriyor.Bu nedenle, htop'a benzer bir Swap sütunu eklemeyeceğim çünkü bu bilgiyi almanın güvenilir bir yolunu bilmiyorum (aslında, bunun mümkün olduğunu düşünmüyorum paylaşılan sayfalar nedeniyle tam bir sayı).
Bulduğum en iyi senaryo bu sayfada: http://northernmost.org/blog/find-out-what-is-using-your-swap/
İşte betiğin bir varyantı ve kök gerekmez:
#!/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
, 738932
kullanılan ücretsiz şovlar iken ...
for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -n
Debian / RH 6x +, Arch, Ubuntu (RH 5x vardır VmSize
) ( kaynak ) için. @Dgunchev gibi daha az toplam takas verir free
. @Tensibai Arch üzerinde çalışmaz; senin awk bir şey eksik olabilir.
top
: northernmost.org/blog/swap-usage-5-years-later
İşte betiğin başka bir varyasyonu, ancak daha okunabilir çıktı vermek istiyordu (kesin sonuç almak için bunu kök olarak çalıştırmanız gerekiyor):
#!/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
yerine comm
de ps
ben aynı adı fakat farklı argümanlar (piton gunicorn süreçlerin bir demet) ile süreçlerin çok şey var çünkü komuta. Yani:ps -p $PID -o args --no-headers
grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'
basitleştirilebilir gibiawk ' /VmSwap/ { print $2 }'
Bu iş parçacığının oldukça eski olduğunu fark ettim, ancak eğer yaptığım gibi, yanılmak durumunda kalırsanız, başka bir cevap: smem kullanın.
İşte size hem nasıl kurulacağını hem de nasıl kullanılacağını söyleyen bir bağlantı:
http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
Çoğu sayfanın yer değiştirdiği işlemi veya çoğu sayfanın yer değiştirmesine neden olan işlemi bulmak istediğinizi tam olarak açık değilsiniz.
İlk olarak top
swap ile çalıştırabilir ve sipariş edebilirsiniz ('Op' tuşuna basın), ikincisi vmstat
için 'so' için sıfır olmayan girişleri çalıştırabilir ve arayabilirsiniz .
Top komutu ayrıca bir işlem için sayfa hatası sayısını görüntüleyen bir alan içerir. Maksimum sayfa hatası olan işlem, en çok değiştirilen işlem olacaktır. Uzun süren cinler için, başlangıçta çok sayıda sayfa hatasına maruz kalabilirler ve sayı daha sonra artmaz. Bu yüzden sayfa hatalarının artmakta olup olmadığını gözlemlememiz gerekir.
Kabuktaki döngüden kaçınan başka bir kod varyantı:
#!/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
}'
Standart kullanım, script.sh
program başına kullanımı rasgele sırayla elde etmek ( awk
karmalarını nasıl sakladığına kadar) veya script.sh 1
çıktıyı pid'e göre sıralamaktır.
Umarım ne yaptığını söylemek için yeterli kod yorum yaptım.
bash
Dizinleri sıralı bir şekilde genişlettiğini unutmayın (sayısal değil, sözcüksel). Rastgele sıra, awk
dizilerini nasıl saklayacağına (karma tablosu) ve for p in pname
bunları nasıl geri alacağına bağlıdır .
/proc/1/status
sonra gelir /proc/1992/status
ve /
9 ascii kodunun üstünde bir ascii kodu vardır. Bu da "rastgele bir düzen" görünümü ve hissi verir. Buraya bir kısayol
/proc/1/status
/proc/1992/status
Siparişin bayt değerine dayandığı C yerel ayarından sonra gelmez . Yerel ayarınızda (veya en_GB.UTF-8
GNU sistemimde) yapar, çünkü /
harmanlama algoritmasında ilk örnekte yok sayılır (ve s
sonra sıralanır 9
). Karşılaştırma printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sort
ile printf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort
. Bunun dışındaki yerel ayarlarda C
, sıralama düzeni genellikle bayt değerine dayalı değildir .
Çünkü top
ya htop
gezen, küçük sistemlerde yüklü değil olabilir /proc
mümkün daima kalmak.
Küçük sistemlerde bile, bir shell
...
Bu daha tam olarak aynı olduğu lolotux senaryo , ancak herhangi bir çatal olmadan grep
, awk
ya da ps
. Bu çok daha hızlı!
Ve benzeri darbe en fakirlerden biri kabuk performansla ilgili olarak, bu komut dosyasının iyi çalışmasını sağlamak için küçük bir çalışma yapıldı tire, busyboxve diğerleri. Sonra, ( Stéphane Chazelas sayesinde ) tekrar çok daha hızlı hale geldi!
#!/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
Çifte alıntı yapmayı unutma "$PROGNAME"
! Stéphane Chazelas'ın yorumuna bakın :
read FIELD PROGNAME < <(
perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
)
echo $FIELD "$PROGNAME"
echo $PROGNAME
Mantıklı sistemde çift alıntı yapmayı denemeyin ve daha önce mevcut mermiyi öldürmeye hazır olun!
Bu çok basit bir senaryo haline geldikçe , zaman daha verimli bir dil kullanarak özel bir araç yazmaya geliyor.
#!/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;
biri ile koşarak olabilir
-c sort by command name
-p sort by pid
-m sort by swap values
by default, output is sorted by status's vmsize
:
, ters eğik çizgi, joker karakter veya kontrol karakterleri içermediğini varsayar .
[1-9]
önce *
hiçbir (yalnızca numaralı yolları saymak içinself
, ne thread-self
)
Name
giriş /proc/*/status
bu bayt değerlerinden bazılarını kodlar. Örneğin deneyin perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/status
. Çok kısa perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
olduğu için, değişkenlerinizi alıntılamayı unuttuğunuzda, bunun gibi şeylerle yapılabilecek hasar sınırlıdır.
Bu uzun tek satırlı web üzerinde farklı bir komut dosyası uyarladı:
{ 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 ; }
Daha sonra bir cronjob içine atmak ve çıktı bir günlük dosyasına yönlendirmek. Buradaki bilgiler Swap:
, smaps dosyasındaki girişleri biriktirmekle aynıdır , ancak emin olmak istiyorsanız şunları kullanabilirsiniz:
{ 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; }
Bu sürümün çıktısı iki sütundadır: pid, takas miktarı. Yukarıdaki sürümde, tr
sayısal olmayan bileşenleri çıkarır. Her iki durumda da, çıktı sayısal olarak pid'e göre sıralanır.
Sanırım top
çok fazla bellek kullanarak aktif süreçleri çalıştırarak ve arayarak iyi bir tahmin yapabilirsiniz . Bunu programlı olarak yapmak daha zordur --- sadece Linux OOM katili buluşsal yöntemleriyle ilgili bitmeyen tartışmalara bakın.
Değiştirme, etkin kullanımda yüklü olandan daha fazla belleğe sahip olmanın bir işlevidir , bu nedenle tek bir işlemde onu suçlamak genellikle zordur. Sorun devam ediyorsa, en iyi çözüm daha fazla bellek takmak veya diğer sistemik değişiklikleri yapmaktır.
Takas kullanarak işlem için toplamlar ve yüzdeler verir
smem -t -p
Kaynak: https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
Takas alanını tam olarak hangi işlemin kullandığını nasıl bulacağımı doğrudan bir cevap bilmiyorum, ancak bu bağlantı yararlı olabilir . İyi bir tane daha burada
Ayrıca, hangi işlemlerin çok fazla bellek kullandığını ve toplamda ne kadar takas kullanıldığını görmek için htop gibi iyi bir araç kullanın.
iotop
çok kullanışlı bir araçtır. İşlem / iş parçacığı başına G / Ç ve takas kullanımının canlı istatistiklerini verir. Varsayılan olarak iş parçacığı başına gösterilir, ancak iotop -P
işlem başına bilgi almak için yapabilirsiniz . Bu, varsayılan olarak kullanılamaz. Rpm / apt üzerinden kurulum yapmanız gerekebilir.
İşte @loolotux'un senaryosuyla aynı çıktıyı veren, ancak çok daha hızlı (daha az okunabilirken) bir sürüm. Bu döngü makinemde yaklaşık 10 saniye sürüyor, sürümüm 0.019 s sürüyor, bu benim için önemliydi çünkü cgi sayfasına dönüştürmek istedim.
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
2015 yılından bu yana eklenen çekirdek yaması SwapPss
( https://lore.kernel.org/patchwork/patch/570506/ ) sonunda, bir işlem çok fazla takas ve sonra çatallanırsa, her ikisi de çatallı işlemler anlamına gelir. her birinin% 50'sini değiştirdiği bildirilecektir. Ve sonra çatallar, her işlem takas sayfaları% 33 sayılır, böylece tüm bu takas kullanımlarını birlikte sayarsanız, işlem sayısıyla çarpılan değer yerine gerçek takas kullanımı elde edersiniz.
Kısacası:
(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)
İlk sütun pid, ikinci sütun KiB'de takas kullanımıdır ve satırın geri kalanı komut yürütülmektedir. Aynı takas sayıları pid'e göre sıralanır.
Yukarıdaki gibi satırlar yayabilir
awk: cmd. line:1: fatal: cannot open file `15407/smaps' for reading (No such file or directory)
bu sadece pid 15407 ile /proc/
yapılan işlemin listede görünmesi ve işlem smaps
dosyasının okunması arasında sona erdiği anlamına gelir . Bu sizin için önemliyse,2>/dev/null
, sonuna . Potansiyel olarak diğer tüm teşhisleri de kaybedeceğinizi unutmayın.
Gerçek dünyadaki örnek durumda, bu, bir sunucuda çalışan her apache çocuğu için ~ 40 MB takas kullanımını bildiren diğer araçları, çocuk başına gerçekten kullanılan 7-3630 KB arasında gerçek kullanıma değiştirir.