[kde-solaris] Memory Usage Redux (memstat.pl)

LeBar, Russell J kde-solaris@mail.kde.org
Fri Mar 21 21:16:01 2003


For those of you interested in getting an idea of how much memory is really
being used by KDE (in general terms) here's a Perl script I wrote. I'm
releasing it licensed under the GPL: http://www.gnu.org/licenses/gpl.txt. It
runs under Solaris 8+ (I believe that's when the pmap command was
introduced).

Example usage (run as root for accurate answers): 

memstat.pl --user joe123  # All of joe123's processes
memstat.pl --app kdeinit     # All kdeinit processes
memstat.pl --user joe123 --app kdeinit   # Just joe123's kdeinit processes.
memstat.pl -u joe123 -a kdeinit  # Same as above but with less typing


#!/usr/local/bin/perl
# This code is released under the GPL. 
# Read the license at http://www.gnu.org/licenses/gpl.txt.

use strict;
use Getopt::Long;
use FileHandle;

#///////////////////////////////////////////////////////////
my %Mem;
my @Procs;
my $App;
my $User;
my $Flags;
my $Total_Total	= 0;
my $Total_Shared  = 0;
my $Total_Private = 0;
my $HELP 		= 0;

#///////////////////////////////////////////////////////////
format procs_top =
Command                                          USER                 PID
-------------------------------------------------------------------------
.

format procs =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<   @>>>>>>>>>       @>>>>>>>>>>>>
$_->[2],                                   $_->[1],         $_->[0]
.               

#///////////////////////////////////////////////////////////
format mem_top =
File                                    Shared Memory      Private Memory
-------------------------------------------------------------------------
.

format mem =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<           @>>>>>>>>>>>>      @>>>>>>>>>>>>
$_,                                     $Mem{$_}->{sha},   $Mem{$_}->{pvt}
.               

#///////////////////////////////////////////////////////////
format totals_top =
TOTALS:    Shared + Private Memory      Shared Memory      Private Memory
-------------------------------------------------------------------------
.

format totals =
                     @>>>>>>>>>>>>      @>>>>>>>>>>>>      @>>>>>>>>>>>>
                     $Total_Total,      $Total_Shared,     $Total_Private
.

#///////////////////////////////////////////////////////////
sub mysort () {
	$Mem{$a}->{pvt} <=> $Mem{$b}->{pvt} || $Mem{$a}->{sha} <=>
$Mem{$b}->{sha} || $a cmp $b;
	}


#///////////////////////////////////////////////////////////
MAIN: {
	my $numopts = @ARGV;
	Getopt::Long::Configure('bundling');
	GetOptions(
          'H|h|v|help|version'	=> \$HELP,
          'u|user=s'			=> \$User,
          'a|app=s'			=> \$App,
          );

	$App  = undef unless defined $App  && $App  ne "";
	$User = undef unless defined $User && $User ne "";

	if((! defined $App && ! defined $User) || $numopts < 1 || $HELP ) {
		print "Usage $0 <[-a/--app App] || [-u/--user User]>\n";
		exit 5;
		}

	foreach ( map { [ (split ' ', $_)[0,1,2] ] } grep !/grep/, `ps -ea
-o pid,user,comm` ) {
		next unless defined $_->[2]; # Avoid zombies and other weird
things
	
		if(      defined $User &&   defined $App ) { next unless
$_->[2] =~ /$App/ && $_->[1] =~ /$User/ }
		elsif(   defined $User && ! defined $App ) { next unless
$_->[1] =~ /$User/	}
		elsif( ! defined $User &&   defined $App ) { next unless
$_->[2] =~ /$App/ 	}
		else                                       { next }

		push @Procs, $_;

		my @pmap = `pmap -x $_->[0]`; shift @pmap; shift @pmap; pop
@pmap; pop @pmap; # Remove the first and last two lines.	
		foreach my $p ( @pmap ) {
			my ( $sha, $pvt, $file ) = (split ' ', $p)[3,4,6];

			if( $file eq '[' ) {
				my $lsb = rindex $p, '[';
				my $rsb = rindex $p, ']';
				$file = substr $p, $lsb, $rsb-$lsb+1;	
				}

			$Mem{$file}->{sha} = $sha unless $sha eq '-';
			next if $pvt eq '-';
			$Mem{$file}->{pvt} += $pvt;
			}
		}
	
	STDOUT->format_name( "procs" );
	STDOUT->format_top_name( "procs_top" );

	foreach ( @Procs ) { write }
	STDOUT->format_lines_left( 0 );
	print "\n\n";
	STDOUT->format_name( "mem" );
	STDOUT->format_top_name( "mem_top" );

	foreach ( sort mysort keys %Mem ) {
		$Mem{$_}->{sha} = 0 unless exists $Mem{$_}->{sha};
		$Mem{$_}->{pvt} = 0 unless exists $Mem{$_}->{pvt};
		write;
		$Total_Shared  += $Mem{$_}->{sha};
		$Total_Private += $Mem{$_}->{pvt}
		}

	$Total_Total = $Total_Shared + $Total_Private;
	STDOUT->format_lines_left( 0 );
	STDOUT->format_name( "totals" );
	STDOUT->format_top_name( "totals_top" );
	write;
	}




Russ LeBar
Enterprise Rent-A-Car  Phone:314-512-3355
Network Management System Administration  Fax:314-512-6002
UNIX System Administrator  Pager:314-841-7565