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