จะทราบได้อย่างไรว่ากระบวนการใดบ้างที่ใช้พื้นที่สว็อปใน Linux?


240

ภายใต้ Linux ฉันจะรู้ได้อย่างไรว่ากระบวนการใดที่ใช้พื้นที่สว็อปมากขึ้น?


30
คำตอบที่คุณยอมรับนั้นผิด ลองพิจารณาเปลี่ยนเป็นคำตอบของ lolotux ซึ่งถูกต้องจริง
jterrace

@ jterrace ถูกต้องฉันไม่มีพื้นที่สว็อปมากเท่ากับผลรวมของค่าในคอลัมน์ SWAP ที่อยู่ด้านบน
akostadinov

1
ไอโซโทปเป็นคำสั่งที่มีประโยชน์มากซึ่งจะแสดงสถิติการใช้งานจริงของ io และ swap ต่อกระบวนการ / เธรด
sunil

@jterrace พิจารณาเซนซึ่งได้รับการยอมรับคำตอบของวันเป็นสิ่งที่ผิด หกปีต่อมาพวกเราที่เหลือก็ไม่รู้ว่าคุณอ้างถึงคำตอบของเดวิดโฮล์ม (คำตอบที่ได้รับการยอมรับในปัจจุบัน ณ วันนี้) หรือคำตอบอื่น ๆ (ดีฉันเห็นคุณยังกล่าวคำตอบเดวิดโฮล์มเป็นที่ไม่ถูกต้องเป็นความคิดเห็นในคำตอบของเขา ... ดังนั้นผมคิดว่าคุณอาจหมายของเขา.)
ดอนแฮทช์

คำตอบ:


106

เรียกใช้ด้านบนOpEnterแล้วกด ตอนนี้กระบวนการควรเรียงลำดับตามการใช้ swap ของพวกเขา

นี่คือการอัปเดตเนื่องจากคำตอบดั้งเดิมของฉันไม่ได้ให้คำตอบที่ถูกต้องสำหรับปัญหาตามที่ระบุไว้ในความคิดเห็น จากคำถามที่พบบ่อย htop :

เป็นไปไม่ได้ที่จะได้ขนาดที่แน่นอนของพื้นที่สว็อปที่ใช้แล้วของกระบวนการ ปลอมข้อมูลนี้ด้วยการทำ SWAP = VIRT - RES แต่นั่นไม่ใช่ตัวชี้วัดที่ดีเพราะสิ่งอื่น ๆ เช่นหน่วยความจำวิดีโอนับเป็น VIRT เช่นกัน (ตัวอย่าง: top บอกว่ากระบวนการ X ของฉันใช้ 81M ของการแลกเปลี่ยน แต่ก็ยัง รายงานว่าระบบของฉันโดยรวมกำลังใช้การสลับเพียง 2M ดังนั้นฉันจะไม่เพิ่มคอลัมน์สลับที่คล้ายกันไปที่ htop เพราะฉันไม่ทราบวิธีที่เชื่อถือได้ในการรับข้อมูลนี้ (จริง ๆ แล้วฉันไม่คิดว่าจะเป็นไปได้ จำนวนที่แน่นอนเนื่องจากเพจที่ใช้ร่วมกัน)


137
จากเอกสารคอลัมน์ SWAP ที่อยู่ด้านบนดูเหมือนจะแสดงให้เห็นว่าจำเป็นต้องมีการแลกเปลี่ยนมากน้อยเพียงใดหากกระบวนการทั้งหมดถูกสลับออกไปแทนที่จะเป็นกระบวนการที่แลกเปลี่ยนจริงในปัจจุบัน จากสิ่งที่ฉันสามารถบอกได้หลังจากการค้นหาสั้น ๆ ไม่มีวิธีใดที่จะกำหนดว่ากระบวนการแต่ละกระบวนการจะถูกสลับเปลี่ยนไปมากน้อยเพียงใดในขณะนี้ ผู้เขียน htop ปฏิเสธที่จะใส่คอลัมน์ดังกล่าวเนื่องจากสิ่งนี้ (ฉันเห็นคอลัมน์ CNSWAP และ NSWAP แต่ดูเหมือนว่าพวกเขาจะไม่ทำอะไรเลยในเครื่องของฉัน): htop.sourceforge.net/index.php?page=faq
yukondude

6
@ yukondude ถูกต้องคอลัมน์ SWAP ที่อยู่ด้านบนเป็นเพียง VIRT - RES และข้อมูลนี้ไร้ประโยชน์ในบริบทนี้ ไม่มีการชดเชยเช่นหน่วยความจำที่แชร์ของ RAM วิดีโอที่แมป กระบวนการบางอย่างอาจไม่ได้รับการอ้างอิงโดยกระบวนการ ในกรณีนี้ไม่จำเป็นสำหรับระบบปฏิบัติการที่จะอ่านไบนารีที่สมบูรณ์จากดิสก์ลงในหน่วยความจำและทำให้ค่าของ RES ไม่รวมส่วนหนึ่งของหน่วยความจำนี้
บาร์ต

ฉันจะลงคะแนนให้มากขึ้นถ้าทำได้ นี่คือการบันทึกเบคอนของฉัน!
atrain

โชคดีที่ความคิดเห็นนั้นมีไว้สำหรับ @jterrace :) (แม้ว่าเป็นที่ยอมรับว่าคุณต้องอ่านพวกเขา: S. ... ไม่แน่ใจว่า atrain หมายถึงอะไรฉันหวังว่ามัน yukondude)
AJP

11
เกี่ยวกับความคิดเห็นที่ไม่ทำงานอีกต่อไป: ดูเหมือนว่าเวอร์ชันบนสุดที่ผ่านมาไม่ได้ตั้งค่า 'O' เป็นกุญแจสำหรับการเลือกฟิลด์การเรียง เมื่อใช้? คีย์คุณสามารถดูชื่อโปรแกรมและเวอร์ชันจริง procps-ng เป็นเวอร์ชันล่าสุด นี่คือส้อมโดยเดฟางและ openSUSE A: gitorious.org/procps หากคุณยังต้องการจัดเรียงในคอลัมน์ SWAP: ใช้ปุ่ม 'f' เพื่อดูฟิลด์ใช้ปุ่มลูกศรเพื่อไปที่ SWAP และใช้ 's' เพื่อตั้งค่าการเรียงแล้ว 'q'
Pieter VN

294

สคริปต์ที่ดีที่สุดที่ฉันพบคือในหน้านี้: http://northernmost.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"

นี่คือสำเนาในกรณีที่ลิงค์เสียชีวิต: gitorious.org/dolanormisc/scripts/blobs/master/getswapused
TautrimasPajarskas

4
ตลก แต่ผมได้รับOverall swap used: 260672 KBในขณะที่การแสดงฟรี738932ที่ใช้ ...
Doncho Gunchev

23
ผลลัพธ์เดียวกันเร็วขึ้นสิบเท่า: 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 มีVmSize) ( แหล่งที่มา ) เช่นเดียวกับ @dgunchev มันจะให้การแลกเปลี่ยนโดยรวมน้อยกว่าfreeมาก @Tensibai ไม่ทำงานบน Arch; awk ของคุณอาจขาดอะไรบางอย่าง
tuk0z

1
กรุณาดูที่สคริปต์เวอร์ชันนี้
F. Hauri

3
ผู้เขียนมีโพสต์ติดตามเกี่ยวกับวิธีการใช้top: northernmost.org/blog/swap-usage-5-years-later
แจ็ค Valmadre

53

นี่คืออีกหนึ่งตัวแปรของสคริปต์ แต่มีจุดประสงค์ที่จะให้ผลลัพธ์ที่อ่านได้มากขึ้น (คุณต้องเรียกใช้สิ่งนี้เป็นรูทเพื่อรับผลลัพธ์ที่แน่นอน):

#!/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
สคริปต์ที่ดีมาก มันให้ข้อมูลเดียวกับโลโกลักซ์ แต่เป็นวิธีที่อ่านได้ดีกว่า
Philipp Wendler

ผลผลิตที่ยอดเยี่ยม ขอบคุณ
Brian Cline

2
สิ่งเดียวที่ผมเปลี่ยนใช้argsแทนcommในpsคำสั่งตั้งแต่ฉันมีจำนวนมากของกระบวนการที่มีชื่อเดียวกัน แต่ข้อโต้แย้งที่แตกต่างกัน (พวงของกระบวนการหลาม gunicorn ก) เช่น:ps -p $PID -o args --no-headers
mgalgs

1
หมายเหตุด้านgrep VmSwap $DIR/status 2>/dev/null | awk '{ print $2 }'สามารถทำให้ง่ายขึ้นเป็นawk ' /VmSwap/ { print $2 }'
Tensibai

12

ฉันสังเกตเห็นว่าเธรดนี้ค่อนข้างเก่า แต่ถ้าคุณบังเอิญสะดุดกับมันอย่างที่ฉันทำไปแล้วคำตอบอื่นคือ: ใช้ smem

นี่คือลิงค์ที่จะบอกคุณทั้งสองวิธีการติดตั้งและวิธีการใช้งาน:

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


อันนี้ดีนะ นี่คือรุ่นดัดแปลงจากบทความนั้นเพื่อแสดง procs เรียงตามการใช้ swap พร้อมเพิ่ม PID: $ สำหรับไฟล์ใน / proc / * / status; do awk '/ ^ Pid | VmSwap | ชื่อ / {printf $ 2 "" $ 3} END {print ""}' $ file; เสร็จสิ้น sort -k 3 -n -r | น้อยลง
Stan Brajewski

คุณควร glob / proc / [1-9] * / สถานะเพื่อไม่รวมรายการพิเศษ / proc สองรายการและคุณสามารถรวมการเรียงลำดับ args เป็น -rnk3
dland

10

ยังไม่ชัดเจนนักถ้าคุณหมายถึงคุณต้องการค้นหากระบวนการที่มีการสลับหน้าเว็บเป็นส่วนใหญ่หรือกระบวนการที่ทำให้หน้าส่วนใหญ่สลับไปมา

สำหรับครั้งแรกที่คุณสามารถเรียกใช้topและสั่งซื้อโดยสลับ (กด 'Op') สำหรับหลังคุณสามารถเรียกใช้vmstatและมองหารายการที่ไม่เป็นศูนย์สำหรับ 'ดังนั้น'


6

คำสั่งด้านบนยังมีฟิลด์เพื่อแสดงจำนวนความผิดพลาดของหน้าสำหรับกระบวนการ กระบวนการที่มีความผิดพลาดสูงสุดที่หน้าจะเป็นกระบวนการที่มีการแลกเปลี่ยนมากที่สุด สำหรับ daemons ที่รันมานานอาจเป็นเพราะพวกเขามีข้อบกพร่องของหน้าจำนวนมากในตอนเริ่มต้นและจำนวนจะไม่เพิ่มขึ้นในภายหลัง ดังนั้นเราต้องสังเกตว่าข้อบกพร่องของหน้านั้นเพิ่มขึ้นหรือไม่


6

ตัวแปรสคริปต์อื่นที่หลีกเลี่ยงการวนซ้ำในเชลล์:

#!/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เรียงลำดับผลลัพธ์ตาม pid

ฉันหวังว่าฉันจะแสดงความคิดเห็นรหัสเพียงพอที่จะบอกว่ามันทำอะไร


1
โปรดทราบว่าการbashขยายไดเรกทอรีในวิธีการเรียงลำดับ (คำศัพท์ไม่ใช่ตัวเลข) ลำดับแบบสุ่มจะลดลงไปตามวิธีการจัดawkเก็บอาร์เรย์ (ตารางแฮช) และวิธีfor p in pnameดึงข้อมูล
Stephane Chazelas

@StephaneChazelas อืมไม่ใช่ศัพท์ศัพท์นั่นคือการเรียงลำดับรหัส ASCII (ตาม/proc/1/statusมาหลังจากนั้น/proc/1992/statusและ/มีรหัส ASCII ด้านบนรหัส 9 ASCII นี้ให้รูปลักษณ์ "ความรู้สึกแบบสุ่ม" ฉันเห็นด้วยกับตารางแฮช awk ฉันเอาช็อตคัตที่นี่อย่าลังเลที่จะแก้ไขคำตอบเพื่อให้มีการระบุแหล่งที่มาในประวัติการแก้ไข
Tensibai

1
/proc/1/statusจะไม่มา/proc/1992/statusในโลแคล C ซึ่งคำสั่งนั้นอ้างอิงตามค่าไบต์ มันทำในสถานที่ของคุณ (หรือใน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นั้นการเรียงลำดับโดยทั่วไปจะไม่ขึ้นอยู่กับค่าไบต์
Stephane Chazelas

@StephaneChazelas จุดที่ดีไม่ได้เกี่ยวกับสถานที่ คุณสามารถแก้ไขเพื่อเพิ่มความแม่นยำได้อีกครั้งดังนั้นเครดิตจะเป็นของคุณ (อย่างน้อยก็ในการแก้ไขประวัติ)
Tensibai

2
เสร็จสิ้น คำตอบนี้ดีกว่าคำตอบที่ได้รับการโหวตมากที่สุดที่นี่ มันสมควรได้รับการโหวตมากขึ้น คำตอบนั้นและคำตอบอื่น ๆ ที่นี่ถูกกล่าวถึงที่เหตุใดการใช้เชลล์ลูปเพื่อประมวลผลข้อความจึงถือเป็นการปฏิบัติที่ไม่ดี สิ่งที่นำฉันมาที่นี่
Stephane Chazelas

6

ยังมีอีกสองสายพันธุ์:

เนื่องจากtopหรือhtopอาจไม่ได้ติดตั้งในระบบขนาดเล็กการเรียกดู/procจึงเป็นไปได้เสมอ

แม้ในระบบขนาดเล็กคุณจะพบshell...

ที่แตกต่าง! (ไม่ทุบตีเท่านั้น)

ตรงนี้เป็นสิ่งเดียวกันกว่าสคริปต์ lolotuxแต่ไม่มีส้อมใด ๆ เพื่อgrep, หรือawk psนี่คือเร็วมาก!

และเป็น เป็นหนึ่งในคนที่ยากจนที่สุด เกี่ยวกับประสิทธิภาพมีการทำงานเล็กน้อยเพื่อให้มั่นใจว่าสคริปต์นี้จะทำงานได้ดี , และอื่น ๆ จากนั้น ( ขอบคุณStéphane Chazelas ) กลายเป็นเร็วขึ้นอีกครั้ง!

#!/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"! ดูความคิดเห็นของStéphane Chazelas :

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

จะถือว่าชื่อกระบวนการไม่มีช่องว่างแท็บ:แบ็กสแลชไวด์การ์ดหรืออักขระควบคุม
Stephane Chazelas

@ StephaneChazelas ขอบคุณ! ฉันเพิ่มมา[1-9]ก่อนแล้ว*สำหรับการนับเส้นทางที่มีหมายเลขเท่านั้น (ไม่ใช่self, หรือthread-self)
F. Hauri

1
รู้จักไวยากรณ์แล้ว แต่ชื่อกระบวนการไม่ได้ อย่างน้อยพูดตัวแปรของคุณ (ไม่ว่าในกรณีใดสคริปต์ของคุณแย่กว่า loloxux มาก)
Stephane Chazelas

1
ชื่อกระบวนการบน Linux สามารถมีค่าไบต์ใด ๆ ก็ได้ แต่ 0 แต่มีความยาวไม่เกิน 15 ไบต์ Nameรายการใน/proc/*/statusถอดรหัสบางส่วนของค่าไบต์เหล่านั้น perl -ne 'BEGIN{$0="\n\t\\"} print if /^Name/' /proc/self/statusลองยกตัวอย่างเช่น เนื่องจากมันสั้นมากความเสียหายที่สามารถทำได้กับสิ่งต่าง ๆ เช่นperl -ne 'BEGIN{$0="/*/*/../../*/*"} print if /^Name/' /proc/self/statusมี จำกัด เมื่อคุณลืมอ้างอิงตัวแปรของคุณ
Stephane Chazelas

1
(อย่างน้อยเวอร์ชั่น perl ที่ฉันเพิ่งลอง) นี้เร็วกว่าคำตอบอื่น ๆอย่างมหาศาล
David Gardner

5

ฉันปรับสคริปต์อื่นบนเว็บให้เป็นหนึ่งซับในแบบยาว:

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

ซึ่งฉันก็โยน cronjob และเปลี่ยนเส้นทางไปยังไฟล์บันทึก ข้อมูลที่นี่เหมือนกับการรวบรวมSwap:รายการในไฟล์ smaps แต่ถ้าคุณต้องการให้แน่ใจคุณสามารถใช้:

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

ผลลัพธ์ของรุ่นนี้อยู่ในสองคอลัมน์: pid, จำนวน swap ในเวอร์ชันด้านบนจะตัดtrส่วนประกอบที่ไม่ใช่ตัวเลข ในทั้งสองกรณีผลลัพธ์จะถูกจัดเรียงตัวเลขโดย pid


2
สิ่งนี้ดี แต่อันแรกเรียงลำดับโดย pid จากน้อยไปหามาก (sort -n) การใช้งานที่ดีกว่าคือการจัดเรียงโดยใช้การสลับตามลำดับจากมากไปน้อย (การใช้มากที่สุดอยู่ด้านหน้าของรายการ) เพื่อให้ได้เปลี่ยน "sort -n" เป็น "sort -n -k 3 -r"
Stan Brajewski


2

ฉันคิดว่าคุณสามารถเดาได้ดีจากการรันtopและค้นหากระบวนการที่ใช้งานอยู่โดยใช้หน่วยความจำจำนวนมาก การทำแบบนี้เป็นเรื่องยาก - เพียงแค่ดูการอภิปรายที่ไม่รู้จบเกี่ยวกับการวิเคราะห์พฤติกรรมของ Linux OOM

การสลับเป็นฟังก์ชั่นที่มีหน่วยความจำในการใช้งานมากกว่าการติดตั้งดังนั้นจึงมักจะตำหนิได้ยากในกระบวนการเดียว หากเป็นปัญหาต่อเนื่องทางออกที่ดีที่สุดคือการติดตั้งหน่วยความจำเพิ่มเติมหรือทำการเปลี่ยนแปลงระบบอื่น ๆ



1

ผมไม่ทราบว่าของคำตอบโดยตรงใด ๆ ที่เป็นวิธีการที่จะค้นหาสิ่งที่ขั้นตอนการใช้พื้นที่ swap แต่การเชื่อมโยงนี้อาจจะเป็นประโยชน์ อีกอันที่ดีอยู่ตรงนี้

นอกจากนี้ให้ใช้เครื่องมือที่ดีเช่น htop เพื่อดูว่ากระบวนการใดที่ใช้หน่วยความจำจำนวนมากและใช้การแลกเปลี่ยนโดยรวมเท่าไร


1

iotopเป็นเครื่องมือที่มีประโยชน์มาก มันให้สถิติสดของ I / O และการใช้งานการแลกเปลี่ยนต่อกระบวนการ / ด้าย โดยค่าเริ่มต้นจะแสดงต่อเธรด แต่คุณสามารถทำได้iotop -Pเพื่อรับข้อมูลต่อกระบวนการ ไม่สามารถใช้งานได้ตามค่าเริ่มต้น คุณอาจต้องติดตั้งผ่าน rpm / apt


1

นี่คือเวอร์ชันที่ให้ผลลัพธ์เหมือนกับสคริปต์โดย @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

1

ตั้งแต่ปี 2558 เคอร์เนลแพตช์ที่เพิ่มSwapPss( https://lore.kernel.org/patchwork/patch/570506/ ) ในที่สุดก็สามารถได้รับการนับการแลกเปลี่ยนตามสัดส่วนซึ่งหมายความว่าหากกระบวนการมีการสลับเป็นจำนวนมากและจากนั้นจะดำเนินการทั้งกระบวนการแยก จะมีการรายงานการแลกเปลี่ยน 50% ต่อครั้ง และถ้าอย่างใดอย่างหนึ่งแล้วส้อมแต่ละกระบวนการจะถูกนับ 33% ของหน้าสลับเปลี่ยนดังนั้นหากคุณนับการแลกเปลี่ยน swap เหล่านั้นทั้งหมดเข้าด้วยกันคุณจะได้รับการใช้งานแลกเปลี่ยนจริงแทนที่จะเป็นมูลค่าคูณด้วยจำนวนกระบวนการ

ในระยะสั้น:

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

คอลัมน์แรกคือ pid คอลัมน์ที่สองคือการใช้ swap ใน KiB และส่วนที่เหลือของบรรทัดคือคำสั่งที่ถูกเรียกใช้งาน จำนวน swap ที่เหมือนกันจะถูกจัดเรียงตาม pid

ด้านบนอาจปล่อยบรรทัดเช่น

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

ซึ่งหมายความว่ากระบวนการที่มี pid 15407 สิ้นสุดระหว่างการดูในรายการ/proc/และอ่านsmapsไฟล์กระบวนการ หากสิ่งนั้นมีความสำคัญกับคุณเพียงเพิ่ม2>/dev/nullไปยังจุดสิ้นสุด โปรดทราบว่าคุณอาจสูญเสียการวินิจฉัยที่เป็นไปได้อื่น ๆ เช่นกัน

ในกรณีตัวอย่างในโลกแห่งความจริงสิ่งนี้จะเปลี่ยนเครื่องมืออื่น ๆ ที่รายงานการใช้ swap ~ 40 MB สำหรับเด็ก apache แต่ละคนที่ทำงานบนเซิร์ฟเวอร์หนึ่งเครื่องเป็นการใช้งานจริงระหว่าง 7-3630 KB ที่ใช้จริงต่อเด็กหนึ่งคน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.