Как узнать какие процессы используют файл подкачки в Linux?



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

845   14  

14 ответов:

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

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

Это не возможно, чтобы получить точный размер используемого пространства подкачки в процесс. 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 вариант! (Не только Баш)

это точно так же, чем сценарий 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 killer.

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

на 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, сумма свопа. В приведенной выше версии,tr удаляет нечисловые компоненты. В обоих случаях вывод сортируется численно по пид.

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

smem -t -p

enter image description here

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

Comments

    Ничего не найдено.