लिनक्स के तहत, मुझे कैसे पता चलेगा कि कौन सी प्रक्रिया स्वैप स्थान का अधिक उपयोग कर रही है?
लिनक्स के तहत, मुझे कैसे पता चलेगा कि कौन सी प्रक्रिया स्वैप स्थान का अधिक उपयोग कर रही है?
जवाबों:
शीर्ष चलाएं फिर दबाएं OpEnter। अब प्रक्रियाओं को उनके स्वैप उपयोग द्वारा हल किया जाना चाहिए।
यहाँ एक अपडेट है क्योंकि मेरा मूल उत्तर समस्या का सटीक उत्तर नहीं देता है जैसा कि टिप्पणियों में बताया गया है। से htop पूछे जाने वाले प्रश्न :
किसी प्रक्रिया के उपयोग किए गए स्वैप स्थान का सटीक आकार प्राप्त करना संभव नहीं है। शीर्ष इस जानकारी को SWAP = VIRT - RES करके बनाता है, लेकिन यह एक अच्छा मीट्रिक नहीं है, क्योंकि अन्य सामान जैसे कि वीडियो मेमोरी VIRT पर भी गिना जाता है (उदाहरण के लिए: शीर्ष कहता है कि मेरी एक्स प्रक्रिया स्वैप के 81M का उपयोग कर रही है, लेकिन यह भी है एक पूरे के रूप में मेरे सिस्टम की रिपोर्ट केवल 2M स्वैप का उपयोग कर रही है। इसलिए, मैं htop के लिए एक समान स्वैप कॉलम नहीं जोड़ूंगा क्योंकि मुझे यह जानकारी प्राप्त करने का एक विश्वसनीय तरीका नहीं पता है (वास्तव में, मुझे नहीं लगता कि इसे प्राप्त करना संभव है। साझा पृष्ठों के कारण एक सटीक संख्या)।
इस पृष्ठ पर मुझे मिली सबसे अच्छी पटकथा: http://norustrimost.org/blog/find-out-what-is-using-your-swap/
यहां स्क्रिप्ट का एक संस्करण है और इसकी कोई जड़ नहीं है:
#!/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
इस्तेमाल किया जाता है ...
for file in /proc/*/status ; do awk '/Tgid|VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | grep kB | sort -k 3 -n
डेबियन / आरएच 6x +, आर्क, उबंटू (आरएच 5x में VmSize
) ( स्रोत ) के लिए है। @Dgunchev की तरह यह बहुत कम कुल स्वैप देता है free
। @ टेंसिबाई आर्क पर काम नहीं करती है; आपके जागने में कुछ कमी हो सकती है।
top
: northernmost.org/blog/swap-usage-5-years-later
यहां स्क्रिप्ट का एक और प्रकार है, लेकिन इसका मतलब है कि अधिक पठनीय आउटपुट (आपको सटीक परिणाम प्राप्त करने के लिए इसे रूट के रूप में चलाने की आवश्यकता है):
#!/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
बजाय उपयोग कर रहा था क्योंकि मेरे पास एक ही नाम के साथ बहुत सारी प्रक्रियाएं हैं, लेकिन विभिन्न तर्क (अजगर गुच्छेदार प्रक्रियाओं का एक गुच्छा) है। Ie:comm
ps
ps -p $PID -o args --no-headers
grep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'
सरल बनाया जा सकता हैawk ' /VmSwap/ { print $2 }'
मैंने देखा कि यह धागा पुराना नहीं है, लेकिन यदि आप इस पर ठोकर खाते हैं, जैसा कि मैंने अभी किया है, तो एक और जवाब है: स्मेम का उपयोग करें।
यहां एक लिंक दिया गया है जो आपको बताता है कि इसे कैसे स्थापित किया जाए और इसका उपयोग कैसे किया जाए:
http://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
यह पूरी तरह से स्पष्ट नहीं है यदि आप का मतलब है कि आप उस प्रक्रिया को ढूंढना चाहते हैं, जिसने सबसे अधिक पृष्ठों की अदला-बदली की है या उस प्रक्रिया को जिसने अधिकांश पृष्ठों को अदला-बदली किया है।
पहले के लिए आप top
स्वैप कर सकते हैं और स्वैप कर सकते हैं (प्रेस कर सकते हैं), बाद के लिए आप दौड़ सकते हैं vmstat
और 'शून्य' के लिए गैर-शून्य प्रविष्टियों की तलाश कर सकते हैं ।
शीर्ष कमांड में एक प्रक्रिया के लिए पृष्ठ दोषों की संख्या प्रदर्शित करने के लिए एक फ़ील्ड भी शामिल है। अधिकतम पृष्ठ दोष वाली प्रक्रिया वह प्रक्रिया होगी जो सबसे अधिक स्वैप कर रही है। लंबे समय तक चलने वाले डेमों के लिए यह हो सकता है कि वे शुरुआत में बड़ी संख्या में पृष्ठ दोषों को उकसाएं और बाद में संख्या में वृद्धि न हो। इसलिए हमें यह देखने की जरूरत है कि क्या पेज दोष बढ़ रहा है।
शेल में लूप से बचने वाला एक और स्क्रिप्ट संस्करण:
#!/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
}'
मानक उपयोग का script.sh
उपयोग प्रति कार्यक्रम यादृच्छिक क्रम (नीचे awk
अपनी हैश को कैसे संग्रहीत करता है) के साथ या script.sh 1
आउटपुट को पिड द्वारा सॉर्ट करने के लिए किया जाता है।
मुझे आशा है कि मैंने यह बताने के लिए कोड की पर्याप्त टिप्पणी की है कि यह क्या करता है।
bash
विस्तृत तरीके से निर्देशिकाओं का विस्तार होता है (लेक्सिकल, संख्यात्मक नहीं)। यादृच्छिक क्रम नीचे है कि awk
इसकी सरणियों (हैश टेबल) को कैसे संग्रहीत किया जाए और for p in pname
उन्हें कैसे पुनर्प्राप्त किया जाए।
/proc/1/status
बाद में आता है /proc/1992/status
और /
9 एससीआई कोड के ऊपर एक एएससीआई कोड है। यह "यादृच्छिक क्रम" रूप देता है और महसूस भी करता है। मैं awk हैश तालिका से सहमत हूं) , मैंने यहाँ एक शार्टकट लिया। बेझिझक, संपादित इतिहास में
/proc/1/status
/proc/1992/status
सी लोकेल के बाद नहीं आएगा जहां ऑर्डर बाइट मान पर आधारित है। यह आपके लोकेल (या मेरे en_GB.UTF-8
GNU सिस्टम पर) में करता है, क्योंकि /
कोलाज़ एल्गोरिथ्म (और s
बाद में 9
) में पहले उदाहरण में अनदेखा किया गया है । तुलना printf '/proc/%s/status\n' 1 1992 | LC_ALL=en_GB.UTF-8 sort
के साथ printf '/proc/%s/status\n' 1 1992 | LC_ALL=C sort
। के अलावा अन्य स्थानों में C
, क्रम क्रम बाइट मान पर आधारित नहीं होता है ।
क्योंकि top
या htop
छोटे सिस्टम पर स्थापित नहीं किया जा सकता है, ब्राउज़िंग /proc
हमेशा संभव है।
यहां तक कि छोटे सिस्टम पर, आपको एक shell
...
यह लोलोटॉक्स लिपि से बिल्कुल समान है , लेकिन बिना कांटे के grep
, awk
या ps
। यह बहुत तेज है!
और जैसे दे घुमा के सबसे गरीबों में से एक है खोल प्रदर्शन के संबंध में, यह सुनिश्चित करने के लिए थोड़ा काम किया गया था कि यह स्क्रिप्ट अच्छी तरह से चलेगी पानी का छींटा, बिजीबॉक्सऔर कुछ अन्य। फिर, ( स्टीफन चेज़लस के लिए धन्यवाद ) फिर से बहुत तेज हो गया!
#!/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
दोहरे उद्धरण के लिए मत भूलना "$PROGNAME"
! देखें स्टीफन चेजलस की टिप्पणी :
read FIELD PROGNAME < <(
perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
)
echo $FIELD "$PROGNAME"
echo $PROGNAME
समझदार प्रणाली पर दोहरे उद्धरण के बिना कोशिश मत करो , और इससे पहले कि मौजूदा खोल को मारने के लिए तैयार रहें!
चूंकि यह इतनी सरल लिपि नहीं है, इसलिए समय आ गया है कि अधिक कुशल भाषा का उपयोग करके एक समर्पित उपकरण लिखा जाए।
#!/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;
एक के साथ भाग सकता है
-c sort by command name
-p sort by pid
-m sort by swap values
by default, output is sorted by status's vmsize
:
, बैकस्लैश, वाइल्डकार्ड या नियंत्रण वर्ण नहीं हैं।
[1-9]
इससे पहले कि *
केवल गिने पथ की गणना के लिए (कोई self
, और न ही thread-self
)
Name
में प्रवेश /proc/*/status
encodes उन बाइट मूल्यों हैं। उदाहरण के लिए प्रयास करें perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/status
। क्योंकि यह बहुत ही कम है, जो नुकसान जैसी चीजों के साथ किया जा सकता है perl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/status
वह तब सीमित है जब आप अपने चरों को उद्धृत करना भूल जाते हैं।
मैंने इस लंबे वन-लाइनर के लिए वेब पर एक अलग स्क्रिप्ट को अनुकूलित किया:
{ 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 ; }
जिसे मैं फिर एक क्रोनजोब और एक अप्रत्यक्ष आउटपुट में रीडायरेक्ट में फेंक देता हूं। यहाँ जानकारी वही Swap:
है जो स्मैप्स फ़ाइल में प्रविष्टियों को जमा कर रही है, लेकिन यदि आप सुनिश्चित होना चाहते हैं, तो आप इसका उपयोग कर सकते हैं:
{ 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; }
इस संस्करण का आउटपुट दो कॉलम में है: पीआईडी, स्वैप राशि। उपरोक्त संस्करण में, tr
गैर-संख्यात्मक घटक स्ट्रिप्स। दोनों मामलों में, आउटपुट को संख्यात्मक रूप से pid द्वारा क्रमबद्ध किया जाता है।
मुझे लगता है कि आप top
बहुत स्मृति का उपयोग करके सक्रिय प्रक्रियाओं को चलाकर और देख कर एक अच्छा अनुमान प्राप्त कर सकते हैं । इस प्रोग्राम को करना कठिन है --- बस लिनक्स OOM किलर ह्यूरिस्टिक्स के बारे में अंतहीन बहस को देखें।
स्वैपिंग सक्रिय उपयोग में अधिक मेमोरी होने का एक फ़ंक्शन है जो इंस्टॉल किया गया है, इसलिए आमतौर पर इसे एक ही प्रक्रिया पर दोष देना मुश्किल है। यदि यह एक निरंतर समस्या है, तो सबसे अच्छा समाधान अधिक मेमोरी स्थापित करना, या अन्य प्रणालीगत परिवर्तन करना है।
स्वैप का उपयोग करके प्रक्रिया के लिए योग और प्रतिशत देता है
smem -t -p
स्रोत: https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/
मैं किसी भी प्रत्यक्ष उत्तर के बारे में नहीं जानता कि कैसे स्वैप प्रक्रिया का उपयोग करने के लिए वास्तव में क्या प्रक्रिया है, हालांकि, यह लिंक सहायक हो सकता है । एक और अच्छा एक यहाँ खत्म हो गया है
इसके अलावा, htop जैसे एक अच्छे टूल का उपयोग करके देखें कि कौन सी प्रक्रिया बहुत अधिक मेमोरी का उपयोग कर रही है और कुल मिलाकर कितना स्वैप उपयोग किया जा रहा है।
iotop
एक बहुत ही उपयोगी उपकरण है। यह I / O के लाइव आँकड़े देता है और प्रति प्रोसेस / थ्रेड का उपयोग स्वैप करता है। डिफ़ॉल्ट रूप से यह प्रति थ्रेड दिखाता है लेकिन आप iotop -P
प्रति प्रक्रिया जानकारी प्राप्त करने के लिए कर सकते हैं । यह डिफ़ॉल्ट रूप से उपलब्ध नहीं है। आपको आरपीएम / एप्ट के जरिए इंस्टॉल करना पड़ सकता है।
यहां एक संस्करण है जो @loolotux द्वारा स्क्रिप्ट के समान आउटपुट करता है, लेकिन बहुत तेज़ है (कम पठनीय है)। उस लूप को मेरी मशीन पर लगभग 10 सेकंड लगते हैं, मेरा संस्करण 0.019 सेकेंड का है, जो मेरे लिए मायने रखता है क्योंकि मैं इसे एक 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
वर्ष 2015 के बाद से कर्नेल पैच जो जोड़ता है SwapPss
( https://lore.kernel.org/patchwork/patch/570506/ ) एक अंत में आनुपातिक स्वैप गणना प्राप्त कर सकता है, जिसका अर्थ है कि यदि किसी प्रक्रिया ने बहुत अधिक स्वैप किया है और फिर यह कांटे, दोनों प्रक्रियाएँ हैं प्रत्येक को 50% स्वैप करने की सूचना दी जाएगी। और अगर या तो कांटे, प्रत्येक प्रक्रिया को स्वैप किए गए पृष्ठों का 33% गिना जाता है तो यदि आप उन सभी स्वैप उपयोगों को एक साथ गिनते हैं, तो आपको प्रक्रिया गिनती द्वारा गुणा किए गए मूल्य के बजाय वास्तविक स्वैप उपयोग मिलता है।
संक्षेप में:
(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)
पहला कॉलम पीआईडी है, दूसरा कॉलम KiB में स्वैप उपयोग है और शेष पंक्ति को निष्पादित किया जा रहा है। पहचान स्वैप स्वैप की गणना पिड द्वारा की जाती है।
ऊपर इस तरह के रूप में लाइनों का उत्सर्जन कर सकते हैं
awk: cmd. line:1: fatal: cannot open file `15407/smaps' for reading (No such file or directory)
जिसका सीधा सा अर्थ है कि प्रक्रिया 15407 के साथ यह प्रक्रिया के लिए सूची में देखने /proc/
और पढ़ने के बीच समाप्त हो गई smaps
। यदि यह आपके लिए मायने रखता है, तो बस 2>/dev/null
अंत में जोड़ें । ध्यान दें कि आप संभावित रूप से किसी अन्य संभावित निदान को भी खो देंगे।
वास्तविक दुनिया के उदाहरण के मामले में, यह अन्य उपकरणों की रिपोर्टिंग में बदलाव करता है ~ एक सर्वर पर चल रहे प्रत्येक अपाचे बच्चे के लिए 40 एमबी स्वैप उपयोग जो वास्तव में प्रति बच्चे 7-3630 केबी के बीच वास्तविक उपयोग होता है।