How to find out which processes are using swap space in Linux?

后端 未结 18 1964
终归单人心
终归单人心 2020-11-27 09:11

Under Linux, how do I find out which process is using the swap space more?

18条回答
  •  春和景丽
    2020-11-27 09:15

    Yet two more variants:

    Because top or htop could be not installed on small systems, browsing /proc stay always possible.

    Even on small systems, you will found a shell...

    A shell variant! (Not bash only)

    This is exactly same than lolotux script, but without any fork to grep, awk or ps. This is a lot quicker!

    And as bash is one of the poorest shell regarding performance, a little work was done to ensure this script will run well under dash, busybox and some other. Then, (thanks to Stéphane Chazelas,) become a lot quicker again!

    #!/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
    

    Don't forgot to double quote "$PROGNAME" ! See Stéphane Chazelas's comment:

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

    Don't try echo $PROGNAME without double quote on sensible system, and be ready to kill current shell before!

    And a perl version

    As this become a not so simple script, time is comming to write a dedicated tool by using more efficient language.

    #!/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,") {
                $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,") {
                        $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;
    

    could by run with one of

    -c  sort by command name
    -p  sort by pid
    -m  sort by swap values
    by default, output is sorted by status's vmsize
    

提交回复
热议问题