How do You Really Measure Linux Bloat?
Different Methods to Query Memory Usage

Akkana Peck
Thursday, August 27, 2009 12:57:13 PM
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
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.
statm
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.
Other Stories on LinuxPlanet
|
ps_mem.py
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
Next: Memory Use Per Process, Graphical Memory Map »