#!/usr/bin/perl use strict; use warnings; my $filter = "-e"; my $list = `ps -o pid,cmd $filter --no-headers`; $list =~ s/^\n$/$1/m; my @processes = (map { /(\d+)\s+(.+)/; {pid => $1, cmd => $2} } split("\n", $list)); for my $proc (@processes) { $proc->{swapped} = 0;#print "/proc/$proc->{pid}/smaps\n"; $proc->{resident} = 0; $proc->{total} = 0; next if !-e "/proc/$proc->{pid}/smaps"; open SMAPS, "{pid}/smaps"; while() { $proc->{swapped} += int($1) if(/Swap:\s+(\d+)/); } close SMAPS; next if !-e "/proc/$proc->{pid}/statm"; open STATM, "{pid}/statm"; ($_ = ) =~ /^\d+ (\d+)/; $proc->{resident} = $1 * 4; # statm is in pages, pages are currently 4k (figure out how to actually get page size) $proc->{total} = $proc->{swapped} + $proc->{resident}; } @processes = sort{ $::a->{total} <=> $::b->{total} } @processes; if ($ARGV[0]) { shift @processes while @processes > $ARGV[0]; } my %longest = (pid => 3, total_str => 5, resident_str => 8, swapped_str => 7); my @units = ('k', 'M', 'G'); for my $p (@processes) { for (('total', 'resident', 'swapped')) { $p->{"${_}_unit"} = 0; my $siz = $p->{$_}; while ($siz >= 1024 && $p->{"${_}_unit"} < @units) { $p->{"${_}_unit"} += 1; $siz /= 1024.0; } $p->{"${_}_str"} = sprintf("%.2f %sB", $siz, $units[$p->{"${_}_unit"}]); } for (keys %longest) { $longest{$_} = length $p->{$_} if (length $p->{$_} > $longest{$_}); } } print "TOTAL". (" "x ($longest{total_str}-5)) . " (RESIDENT". (" "x ($longest{resident_str}-8)) ." + SWAPPED". (" "x ($longest{swapped_str}-7)) .") ". "PID". (" "x ($longest{pid}-3)) ." NAME\n"; print "----------------\n"; my $i = 0; for(@processes) { my %padding = (); foreach my $l (keys %longest) { $padding{$l} = " " x ($longest{$l} - length $_->{$l}); } print "$_->{total_str}$padding{total_str} ". "($_->{resident_str}$padding{resident_str} + $_->{swapped_str}$padding{swapped_str}) ". "$_->{pid}$padding{pid} $_->{cmd}\n" if $_->{resident} > 0; if (++$i == 40) { $i = 0; print "----------------\n"; print "TOTAL". (" "x ($longest{total_str}-5)) . " (RESIDENT". (" "x ($longest{resident_str}-8)) ." + SWAPPED". (" "x ($longest{swapped_str}-7)) .") ". "PID". (" "x ($longest{pid}-3)) ." NAME\n"; print "----------------\n"; } } print "----------------\n" if $i; my ($total, $unit); $total = 0; $total += $_->{resident} for(@processes); for ($unit = 0; $unit < 2 && $total > 1024; $unit++) { $total /= 1024; } printf "Total Resident: %.2f $units[$unit]B\n", $total; $total = 0; $total += $_->{swapped} for(@processes); for ($unit = 0; $unit < 2 && $total > 1024; $unit++) { $total /= 1024; } printf "Total Swapped: %.2f $units[$unit]B\n", $total; $total = 0; $total += $_->{total} for(@processes); for ($unit = 0; $unit < 2 && $total > 1024; $unit++) { $total /= 1024; } printf "Total: %.2f $units[$unit]B\n", $total;