Created
January 10, 2011 12:34
-
-
Save seanosulliv/772722 to your computer and use it in GitHub Desktop.
memuse.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Try to determine how much RAM is currently being used per program. | |
# Notes: | |
# | |
# All interpreted programs where the interpreter is started | |
# by the shell or with env, will be merged to the interpreter | |
# (as that's what's given to exec). For e.g. all python programs | |
# starting with "#!/usr/bin/env python" will be grouped under python. | |
# You can change this by changing comm= to args= below but that will | |
# have the undesirable affect of splitting up programs started with | |
# differing parameters (for e.g. mingetty tty[1-6]). | |
# | |
# For older 2.6 kernels and later 2.4 redhat kernels (rmap vm without smaps) | |
# it can not be accurately determined how many pages are shared | |
# between processes in general or within a program in our case: | |
# http://lkml.org/lkml/2005/7/6/250 | |
# A warning is printed if overestimation is possible. | |
# | |
# The shared calculation below will factor out shared text and | |
# libs etc. within a program, but not between programs. So there | |
# will always be some overestimation. This will be the same for | |
# all processes that just use libc for e.g. but more for others | |
# that use larger shared libs like gnome, kde etc. | |
# | |
# I don't take account of memory allocated for a program | |
# by other programs. For e.g. memory used in the X server for | |
# a program could be determined, but is not. | |
# | |
# This script assumes threads are already merged by ps | |
import sys, os, string | |
PAGESIZE=os.sysconf("SC_PAGE_SIZE")/1024 #KiB | |
our_pid=os.getpid() | |
def shared_val_accurate(): | |
"""http://wiki.apache.org/spamassassin/TopSharedMemoryBug""" | |
kernel_ver=open("/proc/sys/kernel/osrelease").readline()[:3] | |
if kernel_ver == "2.4": | |
if open("/proc/meminfo").read().find("Inact_") == -1: | |
return 1 | |
return 0 | |
elif kernel_ver == "2.6": | |
if os.path.exists("/proc/"+str(os.getpid())+"/smaps"): | |
return 1 | |
return 0 | |
def getShared(pid): | |
if os.path.exists("/proc/"+str(pid)+"/smaps"): | |
shared_lines=[line | |
for line in open("/proc/"+str(pid)+"/smaps").readlines() | |
if line.find("Shared")!=-1] | |
return sum([int(line.split()[1]) for line in shared_lines]) | |
else: | |
return int(open("/proc/"+str(pid)+"/statm").readline().split()[2])*PAGESIZE | |
cmds={} | |
shareds={} | |
for line in os.popen("ps -e -o rss=,pid=,comm=").readlines(): | |
size, pid, cmd = map(string.strip,line.strip().split(None,2)) | |
if int(pid) == our_pid: | |
continue #no point counting this process | |
try: | |
shared=getShared(pid) | |
except: | |
continue #ps gone away | |
if shareds.get(cmd): | |
if shareds[cmd] < shared: | |
shareds[cmd]=shared | |
else: | |
shareds[cmd]=shared | |
#Note shared is always a subset of rss (trs is not always) | |
cmds[cmd]=cmds.setdefault(cmd,0)+int(size)-shared | |
#Add max shared mem for each program | |
for cmd in cmds.keys(): | |
cmds[cmd]=cmds[cmd]+shareds[cmd] | |
sort_list = cmds.items() | |
sort_list.sort(lambda x,y:cmp(x[1],y[1])) | |
sort_list=filter(lambda x:x[1],sort_list) #get rid of zero sized processes (kernel threads) | |
#The following matches "du -h" output | |
def human(num, power="K"): | |
powers=["K","M","G","T"] | |
while num >= 1000: | |
num /= 1024.0 | |
power=powers[powers.index(power)+1] | |
human(num,power) | |
return "%.1f%s" % (num,power) | |
for cmd in sort_list: | |
print "%6s %s" % (human(cmd[1]), cmd[0]) | |
#if not shared_val_accurate(): | |
# sys.stderr.write("\nWarning: Shared memory is not reported correctly by this system.\n") | |
# sys.stderr.write("Values reported could be too large.\n") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment