Post

Find Memory Usage Of An Application / Program In Linux Using Shell Script

This morning i’ll discuss about shell scripts again, this script will explain to calculate memory usage every each program / application.

This script will be test in my machine, of course i will testing in slackware linux. Since memory calculation is rather complex, the script will trying its best to find a more accurate results.

The script use 2 files i.e /proc/…/status [to get name process] and /proc/…/smaps [for memory statistic]. Then script will convert all data into Kb, Mb, Gb. Also make sure you install bc command.

Here this script and i give file name ie memtest.sh:

Shell Scripts Memtest.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/bin/bash
# Make sure only root can run our script

if [ "$(id -u)" != "0" ]; then
   echo "This script must be run as root" 1>&2
   exit 1

fi

### Functions
#This function will count memory statistic for passed PID

get_process_mem ()
{
    PID=$1

#we need to check if 2 files exist
if [ -f /proc/$PID/status ];
then
if [ -f /proc/$PID/smaps ];
then

#here we count memory usage, Pss, Private and Shared = Pss-Private

Pss=`cat /proc/$PID/smaps | grep -e "^Pss:" | awk '{print $2}'| paste -sd+ | bc `
Private=`cat /proc/$PID/smaps | grep -e "^Private" | awk '{print $2}'| paste -sd+ | bc `

#we need to be sure that we count Pss and Private memory, to avoid errors

  if [ x"$Rss" != "x" -o x"$Private" != "x" ];
  then
   let Shared=${Pss}-${Private}
   Name=`cat /proc/$PID/status | grep -e "^Name:" |cut -d':' -f2`

   #we keep all results in bytes

   let Shared=${Shared}*1024
   let Private=${Private}*1024
   let Sum=${Shared}+${Private}

   echo -e "$Private  + $Shared = $Sum \t $Name"
  fi
 fi
fi
}

#this function make conversion from bytes to Kb or Mb or Gb

convert()
{
    value=$1
    power=0

#if value 0, we make it like 0.00

if [ "$value" = "0" ];
then
 value="0.00"
fi

#We make conversion till value bigger than 1024, and if yes we divide by 1024

while [ $(echo "${value} > 1024"|bc) -eq 1 ]
do
 value=$(echo "scale=2;${value}/1024" |bc)
 let power=$power+1
done

#this part get b,kb,mb or gb according to number of divisions

case $power in
 0) reg=b;;
 1) reg=kb;;
 2) reg=mb;;
 3) reg=gb;;
esac

echo -n "${value} ${reg} "
}

#to ensure that temp files not exist

[[ -f /tmp/res ]] && rm -f /tmp/res
[[ -f /tmp/res2 ]] && rm -f /tmp/res2
[[ -f /tmp/res3 ]] && rm -f /tmp/res3

#if argument passed script will show statistic only for that pid, of 
not – we list all processes in /proc/ #and get statistic for all of 
them, all result we store in file /tmp/res

if [ $# -eq 0 ]
then
 pids=`ls /proc | grep -e [0-9] | grep -v [A-Za-z] `
 for i in $pids
 do
 get_process_mem $i >> /tmp/res
 done
else
 get_process_mem $1>> /tmp/res
fi

#This will sort result by memory usage

cat /tmp/res | sort -gr -k 5 > /tmp/res2

#this part will get uniq names from process list, and we will add all lines with same process list
#we will count nomber of processes with same name, so if more that 1 process where will be

# process(2) in output

for Name in `cat /tmp/res2 | awk '{print $6}' | sort  | uniq`
do
count=`cat /tmp/res2 | awk -v src=$Name '{if ($6==src) {print $6}}'|wc -l| awk '{print $1}'`
if [ $count = "1" ];
then
 count=""
else
 count="(${count})"
fi

VmSizeKB=`cat /tmp/res2 | awk -v src=$Name '{if ($6==src) {print $1}}' | paste -sd+ | bc`
VmRssKB=`cat /tmp/res2 | awk -v src=$Name '{if ($6==src) {print $3}}' | paste -sd+ | bc`
total=`cat /tmp/res2 | awk '{print $5}' | paste -sd+ | bc`
Sum=`echo "${VmRssKB}+${VmSizeKB}"|bc`

#all result stored in /tmp/res3 file
echo -e "$VmSizeKB  + $VmRssKB = $Sum \t ${Name}${count}" >>/tmp/res3
done

#this make sort once more.
cat /tmp/res3 | sort -gr -k 5 | uniq > /tmp/res

#now we print result , first header

echo -e "Private \t + \t Shared \t = \t RAM used \t Program"

#after we read line by line of temp file

while read line
do
 echo $line | while read  a b c d e f
 do

#we print all processes if Ram used if not 0
  if [ $e != "0" ]; then

#here we use function that make conversion

  echo -en "`convert $a`  \t $b \t `convert $c`  \t $d \t `convert $e`  \t $f"
  echo ""
  fi
 done
done < /tmp/res

#this part print footer, with counted Ram usage
echo "--------------------------------------------------------"
echo -e "\t\t\t\t\t\t `convert $total`"
echo "========================================================"

# we clean temporary file
[[ -f /tmp/res ]] && rm -f /tmp/res
[[ -f /tmp/res2 ]] && rm -f /tmp/res2
[[ -f /tmp/res3 ]] && rm -f /tmp/res3

see also: Shell script for check health in linux system

Shell Script Result While Run Memtest.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
bash-4.3# chmod +x memtest.sh 
bash-4.3# ./memtest.sh 
Private          +       Shared          =       RAM used        Program
588.27 mb        +       16.92 mb        =       605.19 mb       firefox
140.12 mb        +       404.00 kb       =       140.51 mb       dropbox
121.57 mb        +       15.63 mb        =       137.20 mb       plasmashell
66.44 mb         +       8.48 mb         =       74.93 mb        kwin_x11
38.83 mb         +       3.66 mb         =       42.50 mb        Xorg
28.03 mb         +       9.38 mb         =       37.42 mb        kded5
23.97 mb         +       12.69 mb        =       36.67 mb        plugin-containe
20.35 mb         +       6.22 mb         =       26.57 mb        krunner
17.93 mb         +       7.44 mb         =       25.38 mb        dolphin
9.67 mb          +       4.41 mb         =       14.08 mb        konsole
9.42 mb          +       3.42 mb         =       12.85 mb        httpd(4)
7.70 mb          +       3.41 mb         =       11.12 mb        kwalletd5
6.06 mb          +       3.14 mb         =       9.20 mb         kdeconnectd
8.76 mb          +       203.00 kb       =       8.96 mb         mysqld
8.08 mb          +       791.00 kb       =       8.85 mb         pulseaudio
4.64 mb          +       2.88 mb         =       7.53 mb         ksmserver
6.16 mb          +       1.13 mb         =       7.30 mb         mission-control
5.08 mb          +       1.98 mb         =       7.06 mb         kactivitymanage
5.89 mb          +       614.00 kb       =       6.49 mb         NetworkManager
4.34 mb          +       1.73 mb         =       6.07 mb         kglobalaccel5
4.09 mb          +       1.73 mb         =       5.82 mb         polkit-kde-auth
3.94 mb          +       1.76 mb         =       5.71 mb         kaccess
5.40 mb          +       297.00 kb       =       5.69 mb         gvfsd-fuse
3.71 mb          +       1.84 mb         =       5.56 mb         kuiserver5
3.58 mb          +       1.61 mb         =       5.19 mb         xembedsniproxy
1.76 mb          +       1.92 mb         =       3.68 mb         klauncher
3.08 mb          +       417.00 kb       =       3.48 mb         ModemManager
2.42 mb          +       392.00 kb       =       2.80 mb         polkitd
2.24 mb          +       575.00 kb       =       2.80 mb         gvfs-udisks2-vo
2.21 mb          +       552.00 kb       =       2.75 mb         upowerd
2.07 mb          +       467.00 kb       =       2.53 mb         udisksd
1.72 mb          +       771.00 kb       =       2.47 mb         kscreen_backend
2.11 mb          +       336.00 kb       =       2.44 mb         dbus-daemon(5)
1.98 mb          +       404.00 kb       =       2.38 mb         wpa_supplicant
784.00 kb        +       1.57 mb         =       2.33 mb         file.so
344.00 kb        +       1.79 mb         =       2.13 mb         kdeinit5
972.00 kb        +       769.00 kb       =       1.70 mb         bash(3)
1.28 mb          +       351.00 kb       =       1.63 mb         at-spi-bus-laun
1.06 mb          +       477.00 kb       =       1.53 mb         gvfs-afc-volume
1.21 mb          +       294.00 kb       =       1.50 mb         gvfsd
1.35 mb          +       144.00 kb       =       1.49 mb         obexd
1.08 mb          +       208.00 kb       =       1.28 mb         console-kit-dae
1.03 mb          +       158.00 kb       =       1.18 mb         at-spi2-registr
1.02 mb          +       158.00 kb       =       1.18 mb         gvfs-gphoto2-vo
676.00 kb        +       402.00 kb       =       1.05 mb         gconf-helper
400.00 kb        +       602.00 kb       =       1002.00 kb      sddm
880.00 kb        +       24.00 kb        =       904.00 kb       udevd
856.00 kb        +       22.00 kb        =       878.00 kb       mount.ntfs-3g
644.00 kb        +       156.00 kb       =       800.00 kb       gconfd-2
632.00 kb        +       142.00 kb       =       774.00 kb       gvfs-mtp-volume
528.00 kb        +       244.00 kb       =       772.00 kb       kwrapper5
696.00 kb        +       50.00 kb        =       746.00 kb       ksysguardd
196.00 kb        +       454.00 kb       =       650.00 kb       sddm-helper
472.00 kb        +       113.00 kb       =       585.00 kb       dconf-service
444.00 kb        +       19.00 kb        =       463.00 kb       dhcpcd
48.00 kb         +       371.00 kb       =       419.00 kb       agetty(6)
232.00 kb        +       95.00 kb        =       327.00 kb       cgmanager
152.00 kb        +       118.00 kb       =       270.00 kb       dbus-launch(2)
76.00 kb         +       157.00 kb       =       233.00 kb       startkde
4.00 kb          +       157.00 kb       =       161.00 kb       mysqld_safe
132.00 kb        +       19.00 kb        =       151.00 kb       crond
124.00 kb        +       20.00 kb        =       144.00 kb       syslogd
112.00 kb        +       22.00 kb        =       134.00 kb       acpid
116.00 kb        +       13.00 kb        =       129.00 kb       gpm
96.00 kb         +       15.00 kb        =       111.00 kb       klogd
24.00 kb         +       67.00 kb        =       91.00 kb        ck-launch-sessi
60.00 kb         +       16.00 kb        =       76.00 kb        init
60.00 kb         +       7.00 kb         =       67.00 kb        start_kdeinit
44.00 kb         +       15.00 kb        =       59.00 kb        atd
36.00 kb         +       18.00 kb        =       54.00 kb        inetd
bash-4.3#

Conclusion

I think the memtest.sh with output its great, this find real process every each application/program. The result in above is sample for run memtest.sh, the process will different in machine of each. Thanks!

This post is licensed under CC BY 4.0 by the author.