How do You Really Measure Linux Bloat?
Different Methods to Query Memory Usage
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.
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)
getconf PAGESIZEwill 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:
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