February 17, 2019

How do You Really Measure Linux Bloat?

Different Methods to Query Memory Usage

  • August 27, 2009
  • By Akkana Peck

In the last article, I talked about the different types of Linux memory and how deceptive values like Virtual Size and Resident Set Size can be. Today I'll talk about how you can get more useful numbers so you can figure out which programs really are hogging your computer's RAM.

figure 1
figure 1

You can get that information from the kernel via the handy /proc filesystem. It's all indexed by process ID. Get the process id for the program you're interested in via ps -- you want the number in the PID column. For programs like X and firefox that list multiple processes, start with the biggest one (the one with the biggest numbers in the %CPU and %MEM columns).

Once you have your process ID, look in the /proc/PID directory:

$ ls -F /proc/4500
attr/            cwd@     limits     mountstats  personality  stat     wchan
auxv             environ  maps       net/        root@        statm
clear_refs       exe@     mem        oom_adj     sched        status
cmdline          fd/      mountinfo  oom_score   smaps        syscall
coredump_filter  fdinfo/  mounts     pagemap     stack        task/

For checking memory, the most useful files are statm, maps and smaps. None of these files has much documentation, but what there is can be found in man 5 proc.


The statm file is terse:

$ cat /proc/4500/statm
62372 27178 6455 14 0 50434 0

These numbers represent:

  • total program size (virtual size)
  • resident set size
  • shared pages
  • text (code)
  • (unused on Linux)
  • data + stack
  • (unused on Linux)
The units are pages. How big is a page? getconf PAGESIZE will tell you. It's 4096 on my system.

maps and smaps

maps shows a list of mapped memory regions associated with the process. The fields are:

  • address
  • perms
  • offset
  • dev
  • inode
  • pathname

The pathname is particularly interesting, since that tells you if that region of memory corresponds to a shared library or data file -- just paging through the file can give you an idea what sort of resources the program is using.

smaps shows details of those mapped memory regions. The first line is a repeat of the information from maps. In addition, you can get each region's (virtual) size, its resident set size, the amount of shared memory that's clean (hasn't been written to) versus dirty, and the amount of clean and dirty private (non-shared) memory. Each region looks something like this:

08048000-080bc000 r-xp 00000000 03:02 13130 /bin/bash
Size:               464 kB
Rss:                424 kB
Shared_Clean:       424 kB
Shared_Dirty:         0 kB
Private_Clean:        0 kB
Private_Dirty:        0 kB

Fine, but there's a lot of it! There are over 6200 lines in the smaps file corresponding to my firefox-bin process. How can you make use of that much information?

With a script, of course. No standard distro-installed program makes use of this memory information, but there are several scripts you can download.


ps_mem.py, by P�draig Brady, shows you private and shared memory for all programs running on your system. It combines separate instances of each program, so if you're running bash five times, ps_mem.py will combine the memory used by all of them into one bash number. For each program, it tells you how much of the memory used is private and how much is shared.

Run it as root. The output looks something like this:

$ sudo ps_mem.py
 Private  +   Shared  =  RAM used       Program 

 68.0 KiB +  40.0 KiB = 108.0 KiB       sh
 76.0 KiB +  43.0 KiB = 119.0 KiB       firefox
 84.0 KiB +  43.0 KiB = 127.0 KiB       run-mozilla.sh
164.0 KiB +  45.5 KiB = 209.5 KiB       xinit
276.0 KiB +  42.0 KiB = 318.0 KiB       dbus-launch
196.0 KiB + 164.0 KiB = 360.0 KiB       dbus-daemon
632.0 KiB +  76.5 KiB = 708.5 KiB       fetchmail
468.0 KiB + 255.0 KiB = 723.0 KiB       startx
  1.1 MiB + 329.0 KiB =   1.4 MiB       gconfd-2
  1.2 MiB + 263.5 KiB =   1.5 MiB       mybeepd
  3.0 MiB + 761.5 KiB =   3.7 MiB       openbox
  4.0 MiB + 221.5 KiB =   4.2 MiB       mutt
  3.9 MiB + 496.0 KiB =   4.3 MiB       tcsh (3)
  9.3 MiB +   1.3 MiB =  10.6 MiB       emacs22-gtk
 10.8 MiB +   1.9 MiB =  12.6 MiB       xchat
 15.3 MiB +   2.4 MiB =  17.6 MiB       python2.6 (2)
 98.4 MiB +   2.8 MiB = 101.2 MiB       firefox-bin
                        159.9 MiB

 Private  +   Shared  =  RAM used       Program 

Most Popular LinuxPlanet Stories