
memstat is a small proc-based utility designed to help the system administrator figure out what's consuming memory.  Like ps, it lists all the processes, and how much private memory each is using.  Unlike ps, it also lists all the shared objects (shared libraries and executables) that are in memory, and which processes are using those shared objects.  Here's a brief tutorial:

Suppose you do a ps, and you see this:

root       117  0.0  0.0   812     0   3 SW   Sep  7   0:00 getty
root       118  0.0  0.0   812     0   4 SW   Sep  7   0:00 getty
root       119  0.0  0.0   812     0   5 SW   Sep  7   0:00 getty
root       120  0.0  0.0   812     0   6 SW   Sep  7   0:00 getty
root      5810  0.0  0.0   812     0   1 SW    18:03   0:00 getty

And you think to yourself, 812k for each copy of getty?  That seems excessive!  So, you generate a memstat listing, to figure out why it takes 812k to implement getty.  The listing looks like this:

    224k: PID     1 (/sbin/telinit)
    216k: PID     9 (/sbin/update)
    224k: PID    20 (/sbin/kerneld)
    228k: PID    74 (/sbin/syslogd)
    408k: PID    76 (/sbin/klogd)
    232k: PID    82 (/usr/sbin/rpc.portmap)
    224k: PID    84 (/usr/sbin/inetd)
    344k: PID    87 (/usr/sbin/diald)
    256k: PID    91 (/usr/sbin/diald)
    236k: PID   109 (/usr/sbin/cron)
    224k: PID   117 (/sbin/getty)
    224k: PID   118 (/sbin/getty)
    224k: PID   119 (/sbin/getty)
    224k: PID   120 (/sbin/getty)
    220k: PID   121 (/usr/local/sbin/hayes)
    496k: PID  4595 (/usr/bin/tcsh)
    224k: PID  5810 (/sbin/getty)
    336k: PID  5856 (/bin/sh)
   2380k: PID  5872 (/usr/X11R6/bin/XF86_SVGA)
    276k: PID  5876 (/usr/X11R6/bin/fvwm)
   2016k: PID  5984 (/usr/local/lib/netscape/netscape)
    432k: PID  6129 (/usr/local/bin/rxvt)
    460k: PID  6130 (/usr/bin/tcsh)
    240k: PID  6164 (unknown)
    460k: PID  6165 (/usr/bin/tcsh)
     24k: /lib/ld-linux.so.1  1 9 20 74 76 82 84 87 91 109 117 118 119 120 1...
      8k: /lib/libdl.so  5856 5872 5984
    540k: /usr/lib/libc.so  1 9 20 74 76 82 84 87 91 109 117 118 119 120 121...
     32k: /usr/lib/libm.so  5872
    128k: /lib/libreadline.so.2.0  5856
    224k: /usr/lib/libcurses.so  4595 5856 6130 6165
      4k: /usr/local/sbin/hayes  121
     52k: /usr/local/bin/rxvt  6129
      8k: unknown  6164
     48k: /usr/X11R6/lib/libXpm.so  5876 5984
     72k: /usr/X11R6/lib/libICE.so  5984 6129
     32k: /usr/X11R6/lib/libSM.so  5984 6129
    628k: /usr/X11R6/lib/libX11.so  5876 5984 6129
     40k: /usr/X11R6/lib/libXext.so  5876 5984
     64k: /usr/X11R6/lib/libXmu.so  5984
    260k: /usr/X11R6/lib/libXt.so  5984
    308k: /bin/sh  5856
    252k: /usr/bin/tcsh  4595 6130 6165
   2608k: /usr/X11R6/bin/XF86_SVGA  5872
    112k: /usr/X11R6/bin/fvwm  5876
     12k: /sbin/kerneld  20
     24k: /sbin/syslogd  74
     20k: /sbin/klogd  76
     20k: /sbin/telinit  1
      4k: /sbin/update  9
     12k: /sbin/getty  117 118 119 120 5810
     24k: /usr/sbin/cron  109
     68k: /usr/sbin/diald  87 91
     16k: /usr/sbin/inetd  84
     24k: /usr/sbin/rpc.portmap  82
   4392k: /usr/local/lib/netscape/netscape  5984
--------
  21088k

The first thing you see is these lines, which indicate that each copy of getty has allocated 224k of private data.  Each getty is using a separate 224k.

    224k: PID   117 (/sbin/getty)
    224k: PID   118 (/sbin/getty)
    224k: PID   119 (/sbin/getty)
    224k: PID   120 (/sbin/getty)
    224k: PID  5810 (/sbin/getty)

The next thing you see is this line, which indicates that 16k is being used to hold the getty executable itself.  The executable is shared among processes 117, 118, 119, 120, and 5810 (all the gettys).

     16k: /sbin/getty  117 118 119 120 5810


To explain the 812k figure, you also have to look at these lines, which show that the standard C library is taking up 544k, and that the shared-library loader is taking up 28k.  These two objects are being used by almost all the processes, including all the gettys:

    544k: /usr/lib/libc.so  1 9 20 74 76 82 84 87 91 109 117 118 119 120 121...
     28k: /lib/ld-linux.so.1  1 9 20 74 76 82 84 87 91 109 117 118 119 120 1...

If you add up 16k + 224k + 544k + 28k, you get 812k.

memstat is currently available in source-code form on my web-page.

http://charm.cs.uiuc.edu/~jyelon/software.html

- Josh

