blob: b7d06dca3cedd1790ef0c66184452b702a4c9bd3 [file] [log] [blame]
#!/usr/bin/perl
# **********************************************************
# Copyright (c) 2005-2007 VMware, Inc. All rights reserved.
# **********************************************************
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of VMware, Inc. nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# Prints out summary of memory statistics from a global log file
# This script is a merger of old heapacct.pl and new memsummary.sh
# FIXME: add cmd line arg -v
$verbose = 0;
$debug = 0;
if ($#ARGV < 0) {
print "Usage: $0 <file>\n";
exit 0;
}
$file = $ARGV[0];
open(IN, "< $file") || die "Couldn't open $file\n";
while (<IN>) {
# heap acct: use final printed stats, since using max
if (/Updated-at-end Process.*heap breakdown/) {
while (<IN>) {
if (/^([^:]+): cur=.*max=\s*(\d+)K, \#=\s*(\d+)/){
$hnm[$hnms++]=$1;
$hmax{$1}=$2;
$hnum{$1}=$3;
} else {
last;
}
}
}
if (/^\(Begin\) All statistics/) {
# reset
$hnms = 0;
$pnms = 0;
} elsif (/Peak heap cap|Peak heap claim|Peak heap align|Peak stack|Peak mmap|Peak file|peak cap|Peak spec/) {
if (/^\s*(.*) \(bytes\) :\s*(\d+)/){
print "Matched \"$1\" \"$2\" \"$3\"\n" if ($debug);
$nm=$1;
$val=$2;
$pnm[$pnms++]=$nm;
$p{$nm}=$val;
} else {
print "Error: $_" unless (/Peak special heap units/);
}
} elsif (/Peak total memory from OS :\s*(\d+)/){
$reserved_tot=$1;
} elsif (/Our peak commited capacity \(bytes\) :\s*(\d+)/){
$tot=$1;
}
# stats we don't or haven't always had peaks for
if (/Heap align space \(bytes\) :\s*(\d+)/) {
# old logs don't have this as a peak, so take max printed
if ($1 > $align) {
$align = $1;
}
} elsif (/Heap headers \(bytes\) :\s*(\d+)/) {
# not a peak, so take max printed
if ($1 > $header) {
$header = $1;
}
} elsif (/Heap claimed \(bytes\) :\s*(\d+)/) {
# old logs don't have this as a peak, so take max printed
if ($1 > $claimed) {
$claimed = $1;
}
}
if ($verbose) {
# completely separate numbers: variable-sized frequency
# last printed is fine since these never decrease
if (/Heap allocs in buckets :\s*(\d+)/) {
$bucket = $1;
} elsif (/Heap allocs variable-sized :\s*(\d+)/) {
$variable = $1;
}
}
}
close(IN);
# things we don't have peak for
if (defined($p{'Peak heap claimed'})) {
$claimed = $p{'Peak heap claimed'};
}
$tot_cap = $p{'Peak heap capacity'};
$pnm[$pnms++]='Unused heap (capacity - claimed)';
$p{$pnm[$pnms-1]} = $p{'Peak heap capacity'} - $claimed;
if (!defined($p{'Peak heap align space'})) {
$pnm[$pnms++]='(Estimated) Peak heap align space';
$p{$pnm[$pnms-1]} = $align;
}
# FIXME: don't have peak
$pnm[$pnms++]='(Estimated) Peak heap headers';
$p{$pnm[$pnms-1]} = $header;
printf "%35s 100.00%% %10d KB\n", "TOTAL COMMITTED MEMORY", $tot/1024;
printf "%35s %6.2f%% %10d KB\n", "TOTAL RESERVED (non-vmm) MEMORY",
100*$reserved_tot/$tot, $reserved_tot/1024;
for ($i=0; $i<$pnms; $i++) {
printf "%35s %6.2f%% %10d KB\n", $pnm[$i],
100*$p{$pnm[$i]}/$tot, $p{$pnm[$i]}/1024;
}
for ($i=0; $i<$hnms; $i++) {
printf "%35s %6.2f%% %10d KB\n", $hnm[$i],
100*1024*$hmax{$hnm[$i]}/$tot, $hmax{$hnm[$i]};
$hsum += $hmax{$hnm[$i]};
}
if ($verbose) {
printf "Sum of heap acct is %10d KB\n", $hsum;
printf "Adding special %10d\n", $p{'Peak special heap capacity'}/1024;
printf "Adding align %10d\n", $p{'Peak heap align space'}/1024;
$hsum += $p{'Peak heap align space'}/1024;
$hsum += $p{'Peak special heap capacity'}/1024;
# FIXME: this often comes out negative, presumably b/c the heapacct
# maxes are not all simultaneous
printf "Rest of heap: %10d KB\n", ($p{'Peak heap capacity'}/1024) - $hsum;
}
if ($verbose) {
# FIXME: could print out detailed bucket info w/ new stats in logfiles
$tot_alloc = $bucket + $variable;
printf "Tot alloc: %10d\n", $tot_alloc;
printf "Buckets: %10d => %7.3f%%\n", $bucket, 100*$bucket/$tot_alloc;
printf "Variable: %10d => %7.3f%%\n", $variable, 100*$variable/$tot_alloc;
}