Как узнать, какие процессы используют swap space в Linux?

в Linux, как узнать, какой процесс использует пространство подкачки больше?

14 ответов


Run top нажмите клавишу OpEnter. Сейчас процессы должны быть отсортированы по их использованию свопа.

вот обновление, поскольку мой оригинальный ответ не дает точного ответа на проблему, как указано в комментариях. От htop FAQ:

невозможно получить точный размер используемого пространства подкачки процесс. Top подделывает эту информацию, делая SWAP = VIRT - RES, но это не очень хорошая метрика, потому что другие вещи, такие как видеопамять рассчитывает и на VIRT (например: top говорит, что мой процесс X использует 81M свопа, но он также сообщает, что моя система в целом использует только 2M о свопе. Поэтому я не буду добавлять аналогичный столбец подкачки в htop потому что я не знаю надежного способа получить эту информацию (на самом деле, Я не думаю, что можно получить точное число, из-за общего страницы.)


лучший скрипт, который я нашел, находится на этой странице: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  }'`
    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"

вот еще один вариант скрипта, но предназначенный для более читаемого вывода (вам нужно запустить его как root, чтобы получить точные результаты):

#!/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 `;
SORT="kb";                 # {pid|kB|name} as first parameter, [default: kb]
[ "" != "" ] && { SORT=""; }

[ ! -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  }'`
    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}/";

это не совсем ясно, если вы имеете в виду, что вы хотите найти процесс, который имеет большинство страниц поменялись местами или процесс, который вызвал большинство страниц быть заменены.

для первого вы можете запустить top и заказ по свопу (нажмите "Op"), для последнего вы можете запустить vmstat и найдите ненулевые записи для "so".


Я заметил, что эта нить довольно старая, но если вы случайно наткнетесь на нее, как я только что сделал, другой ответ: используйте smem.

вот ссылка, которая говорит вам, как установить его и как его использовать:

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


верхняя команда также содержит поле для отображения количества ошибок страницы для процесса. Процесс с максимальными ошибками страницы будет процессом, который обменивается больше всего. Для длительно работающих демонов может быть, что они несут большое количество ошибок страницы в начале, и число не увеличивается позже. Таким образом, мы должны наблюдать, увеличивается ли ошибка страницы.


другой вариант сценария, избегающий цикла в оболочке:

#!/bin/bash
grep VmSwap /proc/[0-9]*/status | awk -F':' -v sort="" '
  {
    split(,pid,"/") # Split first field on /
    split(,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 чтобы получить использование в программе со случайным порядком (вплоть до how awk сохраняет свои хэши) или script.sh 1 для сортировки выходных данных по pid.

надеюсь, я прокомментировал код достаточно, чтобы сказать, что он делает.


еще два варианта:

A shell вариант! (Не только bash)

это точно так же, чем сценарий lolotux, но без какой-либо вилки до grep, awk или ps. Это намного быстрее!

и Баш - одна из беднейших shell что касается производительности, была проделана небольшая работа, чтобы гарантировать, что этот скрипт будет работать хорошо под тире, busybox и и какой-то другой. Затем (спасибо Стефан 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" ! См.Chazelas Стефана:

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

не пытайся echo $PROGNAME без двойной цитаты на разумной системе, и будьте готовы убить текущую оболочку раньше!

и perl версия

как это будет не так просто сценарий, время идет к напишите специальный инструмент, используя более эффективный язык.

#!/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+= if /^VmSwap:\s+(\d+)\s/;
            $nam= 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+= 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

Я полагаю, вы могли бы получить хорошее предположение, запустив top и ищет активные процессы, использующие много памяти. Сделать это программно сложнее - - - просто посмотрите на бесконечные дебаты о эвристике убийцы Linux OOM.

замена-это функция наличия большего объема памяти в активный использование, чем установлено, поэтому обычно трудно обвинить его в одном процессе. Если это постоянная проблема, лучшим решением является установка большего объема памяти или создание других системных изменения.


на MacOSX вы также запускаете верхнюю команду, но вам нужно ввести "o", затем" vsize", затем введите.


Я не знаю прямого ответа, как найти, какой именно процесс использует пространство подкачки, однако эта ссылка может быть полезны. Еще один хороший -здесь

кроме того, используйте хороший инструмент, как htop, чтобы увидеть, какие процессы используют много памяти и сколько своп в целом используется.


iotop - Это очень полезный инструмент. Он дает живую статистику ввода-вывода и использования подкачки на процесс/поток. По умолчанию он отображается в потоке, но вы можете сделать iotop -P для получения информации о процессе. По умолчанию это недоступно. Возможно, вам придется установить через rpm / apt.


я адаптировал другой скрипт в Интернете к этому длинному однострочному:

 { date;for f in /proc/[0-9]*/status; do 
   awk '{k[]=} 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+=} END { if (s) print FILENAME,s }' $m 2>/dev/null;
  done | tr -dc ' [0-9]\n' |sort -k 1n; }

выход этой версии находится в двух столбцах: pid, swap amount. В приведенной выше версии,tr удаляет нечисловые компоненты. В обоих случаях выходные данные сортируются численно пид.


дает итоги и проценты для процесса с помощью swap

smem -t -p

enter image description here

источник:https://www.cyberciti.biz/faq/linux-which-process-is-using-swap/