Files
oracle/tpt/tools/unix/procmm.sh
2026-03-12 21:23:47 +01:00

135 lines
5.9 KiB
Bash

#!/usr/bin/sh
################################################################################
# Copyright 2018 Tanel Poder. All rights reserved. More info at http://tanelpoder.com
# Licensed under the Apache License, Version 2.0. See LICENSE.txt for terms & conditions.
#
# Script: procmm.sh (Process Memory Matrix) v1.03
#
# Purpose: Show process memory usage for different mappings and segment types
#
# Copyright: Copyright (c) 2010 Tanel Poder ( http://tech.e2sn.com )
# All rights reserved.
#
# ------------------------------------------------------------------------------
#
# Usage: procmm.sh [-t|-a] <pidlist>
#
# Without any special options procmm.sh will show you a matrix
# of the processes address space segment types and their respective
# memory usages/reservations, separately for every process in the
# pidlist.
#
# -t option will only show total memory usage of all processes
# listed in pidlist. Any ANON memory usage and swap reservation
# for *shared* mappings (mapped binaries, libraries, shared memory
# segments - Oracle SGA) is not shown.
# Note that pmap command is not cheap one, so you probably do not
# want to run it over many processes frequently
#
# -a option will list ANON memory usage and swap reservation also for
# shared mappings. The -t and -a options are mutually exclusive
# as it doesn not make sense to sum together the same shared mapping
# memory usage of multiple processes.
#
# Comments: This script currently only works on Solaris as the pmap command
# on other platforms doesnt currently show all required info. On
# Linux it will be possible to read this info from proc filesystem (TODO)
#
# If you are getting "address space is changing" errors from pmap then try
# again or suspend the process for duration of this script run.
# NB! Suspending processes may be dangerous in some cases (such as when
# it is holding a hot latch) so you better know what you are doing.
#
################################################################################
get_matrix() {
p_pid="$1"
#[ "$1" -eq 0 ] && p_pid="all" || p_pid=$1
#pmap -x $p_pid | tr '[]' ' ' | egrep -v "^ *Address|^---------|total Kb|^[0-9]*:" | nawk ''
join -j 1 /tmp/procmm-x.$$ /tmp/procmm-s.$$ > /tmp/blah
join -j 1 /tmp/procmm-x.$$ /tmp/procmm-s.$$ | sed 's/ism shmid/ism_shmid/g' | tr '[]' ' ' | egrep -v "^ *Address|^---------|total Kb|^[0-9]*:" | nawk '
{
item=$7
#print "before", s
sub(/.*\.so.*/, "lib", item)
#print "after", s
#item = gensub(/.*\.so.*/, "lib", "g", $7)
#item = gensub(/lib.+|ld\..+/, "lib", "g", $7)
#print $7 " = " item
vmem[item] += $2
rss[item] += $3
anon[item] += $4
locked[item] += $5
swap[item] += $9
#print $0
}
END {
printf "%6-s %20s %12s %12s %12s %12s %12s\n", "PID", "SEGMENT_TYPE", "VIRTUAL", "RSS", "ANON", "LOCKED", "SWAP_RSVD"
printf "------ -------------------- ------------ ------------ ------------ ------------ ------------\n"
for (x in vmem) {
printf "%6-d %20s %12d %12d %12d %12d %12d\n", '$p_pid', x, vmem[x], rss[x], anon[x], locked[x], swap[x]
total_vmem += vmem[x]
total_rss += rss[x]
total_anon += anon[x]
total_locked += locked[x]
total_swap += swap[x]
}
printf "------ -------------------- ------------ ------------ ------------ ------------ ------------\n"
printf "%6-d %20s %12d %12d %12d %12d %12d\n\n", '$p_pid', "TOTAL(kB)", total_vmem, total_rss, total_anon, total_locked, total_swap
}
'
}
echo "\n-- procmm.sh: Process Memory Matrix v1.03 by Tanel Poder ( http://tech.e2sn.com )"
if [ $# -lt 1 ] ; then
echo "\nUsage:\n"
echo " $0 [-a|-t] <pidlist>\n"
echo " Option -a would report swap reservations and anonymous memory"
echo " for shared mappings (like Oracle SGA) too\n"
exit 1
fi
# defaults
pmap_option=""
compute_total=0
case "$1" in
"-a") pmap_option="a" ; shift ;;
"-t") compute_total=1 ; shift ;;
esac
echo "-- All numbers are shown in kilobytes\n"
pidlist="$*"
#echo $pidlist
if [ $compute_total -eq 0 ]; then
for pid in $pidlist; do
# ps -opid,vsz,rss,args -p $pid | nawk '/ *[0-9]+/{ printf "-- ps info: PID=%d VSZ=%d RSS=%d ARGS=%s\n\n", $1,$2,$3,$4 }'
rm -f /tmp/procmm-x.$$ /tmp/procmm-s.$$
pmap -x$pmap_option $pid | sed 's/ism shmid/ism_shmid/g' | tr '[]' ' ' | egrep -v "^ *Address|^---------|total Kb|^[0-9]+:" > /tmp/procmm-x.$$
pmap -S$pmap_option $pid | sed 's/ism shmid/ism_shmid/g' | tr '[]' ' ' | egrep -v "^ *Address|^---------|total Kb|^[0-9]+:" > /tmp/procmm-s.$$
get_matrix $pid
rm -f /tmp/procmm-x.$$ /tmp/procmm-s.$$
done
else
rm -f /tmp/procmm-x.$$ /tmp/procmm-s.$$
printf "Total PIDs %d, working: " $#
for pid in $pidlist; do
# ps -opid,vsz,rss,args -p $pid | nawk '/ *[0-9]+/{ printf "-- ps info: PID=%d VSZ=%d RSS=%d ARGS=%s\n\n", $1,$2,$3,$4 }'
pmap -x$pmap_option $pid | sed 's/ism shmid/ism_shmid/g' | tr '[]' ' ' | egrep -v "^ *Address|^---------|total Kb|^[0-9]*:" >> /tmp/procmm-x.$$
pmap -S$pmap_option $pid | sed 's/ism shmid/ism_shmid/g' | tr '[]' ' ' | egrep -v "^ *Address|^---------|total Kb|^[0-9]*:" >> /tmp/procmm-s.$$
printf "."
done
printf "\n\n"
get_matrix 0
echo "-- Note that in Total (-t) calculation mode it makes sense to look into ANON and SWAP_RSVD"
echo "-- totals only as other numbers may be heavily \"doublecounted\" due to overlaps of shared mappings\n"
rm -f /tmp/procmm-x.$$ /tmp/procmm-s.$$
fi