A bash script, reporting how much memory a process is using at the time.
GOAL

Every process on a server allocates some amount of memory to function correctly. If a process fails to allocate enough memory, it fails to start or to function properly.

Sometimes you may wish to know which process eats up the server memory. For this purpose, there are lots of built-in utilities like top, ps, vmstat, etc. But most of them do not tell you exactly how much memory a process is using at that time. For instance, why the ps is not an accurate tool to use for this intent.

SOLUTION

You can you the smem utility for this purpuse.

smem is a tool that can give numerous reports on memory usage on Linux systems. Unlike existing tools, smem can report proportional set size (PSS), which is a more meaningful representation of the amount of memory used by libraries and applications in a virtual memory system.

Because large portions of physical memory are typically shared among multiple applications, the standard measure of memory usage known as resident set size (RSS) will significantly overestimate memory usage. PSS instead measures each application's "fair share" of each shared area to give a realistic measure.

But my post is not about the smem. In this post, I provide an alternative script to the smem utility. It makes sense when there is no way to install the smem or a similar tool on the server.

The memu.sh is the bash script that parses /proc/[pid]/smaps files and returns aggregated data per process. The script can be executed by any user, but only the root can display information for all processes of the server. Non-root users can display details about owned processes only.

EXAMPLE
#########################################
## Download the memu.sh script and convert the script from 
## DOS text file format to UNIX text file format
##########################################

{
wget https://dbpilot.net/wp-content/uploads/2022/01/memu.v002.zip --no-check-certificate
unzip memu*.zip
chmod 500 memu.sh
dos2unix memu.sh
}

## Note: It's mandatory to convert the script to  Unix format.
## Otherwise the following error will appear right after the script has been run

[root@word ~]# ./memu.sh
-bash: ./memu.sh: /bin/bash^M: bad interpreter: No such file or directory
##########################################
## Display memory usage for every process
## Sort by PID (default)
##########################################

[root@dbpilot ~]# ./memu.sh
------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
     Process   Username        Swapped(Mb)     Unique(Mb)     Shared(Mb)        Rss(Mb)        Pss(Mb)      Command
------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
           1   root                    0.0            4.5            5.4            9.9            5.3   /usr/lib/systemd/systemd --swi
         583   root                    0.0            2.2            3.6            5.8            3.0   /usr/lib/systemd/systemd-journ
         615   root                    0.0            2.0            4.2            6.2            2.5   /usr/sbin/lvmetad -f


...
        7551   oracle                  0.0            4.2           73.0           77.2            6.7   ora_w007_tst19c
        8619   oracle                  0.0            6.1          108.9          115.1           16.0   ora_m001_tst19c
       10146   oracle                  0.0            5.7          103.3          109.0           14.4   ora_m004_tst19c
       11358   oracle                  0.0            6.0           70.1           76.1           10.7   oracle+ASM_m004_tst19c (DESCRI
       11360   oracle                  0.0            3.1           60.7           63.8            5.9   asm_m000_+ASM
       11386   root                    0.0            0.2            2.7            2.9            0.4   /bin/bash ./memu.sh
------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
       Total                           0.0          999.9         6500.4         7500.7         1367.5
##########################################
## Display memory usage for every process. 
## Sort by the Unique(Mb) column
##########################################

[root@dbpilot ~]# ./memu.sh sort=u
------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
     Process   Username        Swapped(Mb)     Unique(Mb)     Shared(Mb)        Rss(Mb)        Pss(Mb)      Command
------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------

...
        2155   oracle                  0.0           56.7           57.0          113.8           74.9   /u01/app/19c/grid/bin/ohasd.bi
        2347   oracle                  0.0           79.9           56.5          136.5           98.2   /u01/app/19c/grid/bin/oraagent
        2772   oracle                  0.0           96.2           65.5          161.7           98.8   ora_mman_tst19c
        2849   oracle                  0.0          171.5          164.1          335.6          196.8   ora_mmon_tst19c
------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
       Total                           0.0         1003.2         6559.5         7562.7         1370.7
##########################################
##  Display memory usage for the process with pid 2849. 
##########################################

[root@dbpilot ~]# ./memu.sh pid=2849
--------------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
Date                        Process   Username        Swapped(Mb)     Unique(Mb)     Shared(Mb)        Rss(Mb)        Pss(Mb)      Command
--------------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
11 Jan 2022 21:57:25           2849   oracle                  0.0          171.5          164.1          335.6          196.8   ora_mmon_tst19c
##########################################
## Display memory usage for the process with pid 2849. 
## Report every 5 seconds.
##########################################

[root@dbpilot ~]# ./memu.sh pid=2849 watch=5
--------------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
Date                        Process   Username        Swapped(Mb)     Unique(Mb)     Shared(Mb)        Rss(Mb)        Pss(Mb)      Command
--------------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------   ------------
11 Jan 2022 21:57:54           2849   oracle                  0.0          171.5          164.1          335.6          196.8   ora_mmon_tst19c
11 Jan 2022 21:57:59           2849   oracle                  0.0          171.5          164.1          335.6          196.8   ora_mmon_tst19c
11 Jan 2022 21:58:05           2849   oracle                  0.0          171.5          164.1          335.6          196.8   ora_mmon_tst19c
^C
##########################################
## Display the script's help
##########################################

[root@dbpilot ~]# ./memu.sh help

     ## Display memory usage information for all processes

     ./memu.sh

     ## Sort memory usage information by a column
     ## Pid -> pr, Swapped -> sw, Unique -> u, Shared -> s, Rss -> r, Pss -> p

     ./memu.sh sort=u

     ## By default the script display only first 30 characters of a command
     ## To display whole command use cmdfull argument

     ./memu.sh cmdfull

     ## Display memory usage information for a specific process, eg with pid 123

     ./memu.sh pid=123

     ## Update memory usage information every 10 seconds for the pid 123

     ./memu.sh pid=123 watch=10

     ## Reference Doc : What's the meaning of each field in /proc/[pid]/smaps?
     ## Reference Url : https://access.redhat.com/solutions/23894

     Unique = Private_Clean + Private_Dirty
     Shared = Shared_Clean + Shared_Dirty
     Rss(Resident set size) = Unique[Private_Clean + Private_Dirty] + Shared[Shared_Clean + Shared_Dirty]
     Pss(Proportional set size) = Unique(Private_Clean + Private_Dirty) + Shared/"Number of processes sharing the same memory"

Written At
11 JAN 202222:00
Red Hat Release
7.x x64 - 8.x x64