#!/bin/sh # # Location: http://www.groks.org/dirty-memory.sh # Author: Stephen Deasey # Time-stamp: "2008-11-01 03:34:30" # # Which shared libraries/objects are causing the most dirty memory # (private + shared) accross all processes on the system (in kb)? # # sudo dirty-memory # # As above, but only for the processes belonging to a single user: # # dirty-memory $UID # # The second and third columns are the private and shared dirty memory, accross # all processes in the system. The first column is the total of these two. # The fourth column is the number of processes sharing this memory. The fifth # column is the library, executable, heap, stack or mmapped file. # # Example output: # # $ sudo dirty-memory | grep -v heap | tail # 416 400 16 (70) /lib/libdl-2.8.so # 420 420 0 (1) /dev/shm/pulse-shm-276328216 # 456 456 0 (1) [stack]:/usr/bin/emacs-23.0.60:3519 # 536 536 0 (14) /usr/lib/libbonobo-2.so.0.0.0 # 644 644 0 (1) /usr/lib/xulrunner-1.9/libxul.so # 660 644 16 (98) /lib/ld-2.8.so # 788 780 8 (98) /lib/libc-2.8.so # 904 904 0 (25) /usr/lib/libORBit-2.so.0.1.0 # 4708 4 4704 (15) /SYSV00000000 # 9768 9768 0 (1) /usr/bin/emacs-23.0.60 # # - libc and ld are linked into all (98) processes running on the system. # # - Emacs is using the most stack space at 456k. # # - libxul is the library causing the single largest chunk of dirty # memory, although it is only mapped into a single process. # # - libORBit is causing more dirty memory than libxul overall, but this # is because it is mapped into 25 processes. # function main { if [ $# = 0 ]; then awkmaps /proc/[1-9]*/smaps | sort -n else SMAPS=$(find /proc/[1-9]*/smaps -maxdepth 1 \ -uid $1 ! -samefile /proc/self/smaps ! -samefile /proc/$$/smaps \ -printf "%p ") awkmaps $SMAPS | sort -n fi } function awkmaps { exec awk ' /[0-9a-f]+-[0-9a-f]+ / { current = (NF >= 6 ? $6 : "[heap]") if (current == "[heap]" || current == "[stack]") { pid = smapspid(FILENAME) current = current ":" exefile(pid) ":" pid } process[FILENAME, current] += 1 if (process[FILENAME, current] == 1) { all[current] += 1 } } /Private_Dirty/ { if ($2 > 0) { private[current] += $2 } } /Shared_Dirty/ { if ($2 > 0) { shared[current] += $2 } } END { for (so in all) { total = private[so] + shared[so] if (total > 0) { printf("%d %d %d (%d) %s\n", total, private[so], shared[so], all[so], so) } } } function smapspid(smapsfile, a) { split(smapsfile, a, "/") return a[3] } function exefile(pid, lscmd) { lscmd = "ls -l /proc/" pid "/exe" lscmd | getline close(lscmd) return $10 } ' $@ } main "$@"