From 04f55519b5cd2a736eb939a12eef97a40a6c218c Mon Sep 17 00:00:00 2001 From: Mark Dewing Date: Thu, 19 Jan 2017 14:40:56 -0600 Subject: [PATCH] Nexus: Display memory of child processes Currently the polling output only shows the memory of the python process running Nexus. Show the memory used by all the child processes as well. --- nexus/library/memory.py | 77 +++++++++++++++++++++++++++----- nexus/library/project_manager.py | 2 +- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/nexus/library/memory.py b/nexus/library/memory.py index ff3571307..ff529f8da 100644 --- a/nexus/library/memory.py +++ b/nexus/library/memory.py @@ -2,6 +2,11 @@ ## (c) Copyright 2015- by Jaron T. Krogel ## ################################################################## +###################################################################### +# The following is adapted from +# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286222 +# Python Cookbook, by Jean Brouwers +###################################################################### #====================================================================# # memory.py # @@ -21,44 +26,92 @@ import os -_proc_status = '/proc/%d/status' % os.getpid() _scale = {'kB': 1024.0, 'mB': 1024.0*1024.0, 'KB': 1024.0, 'MB': 1024.0*1024.0} -def _VmB(VmKey): +def _VmB(VmKey, pid=None): '''Private. ''' - global _proc_status, _scale + global _scale # get pseudo file /proc//status + + if not pid: + pid = os.getpid() + proc_status = '/proc/%d/status' % pid try: - t = open(_proc_status) + t = open(proc_status) v = t.read() t.close() except: return 0.0 # non-Linux? # get VmKey line e.g. 'VmRSS: 9999 kB\n ...' - i = v.index(VmKey) - v = v[i:].split(None, 3) # whitespace + try: + i = v.index(VmKey) + v = v[i:].split(None, 3) # whitespace + except ValueError: + return 0.0 + if len(v) < 3: return 0.0 # invalid format? # convert Vm value to bytes return float(v[1]) * _scale[v[2]] +def get_children(pid): + proc_children = '/proc/%d/task/%d/children'%(pid,pid) + try: + t = open(proc_children,'r') + v = t.read() + t.close() + except: + return [] -def memory(since=0.0): + children = [int(c) for c in v.split()] + return children + + +def all_children(pid=None): + if not pid: + pid = os.getpid() + + child_list = get_children(pid) + all_list = child_list[:] + for child_pid in child_list: + child2 = all_children(child_pid) + all_list.extend(child2) + return all_list + + +def memory(since=0.0, children=False): '''Return memory usage in bytes. ''' - return _VmB('VmSize:') - since + mem = 0.0 + if children: + for child_pid in all_children(): + mem += _VmB('VmSize:',pid=child_pid) + mem += _VmB('VmSize:') - since + return mem -def resident(since=0.0): +def resident(since=0.0, children=False): '''Return resident memory usage in bytes. ''' - return _VmB('VmRSS:') - since + mem = 0.0 + if children: + for child_pid in all_children(): + mem += _VmB('VmRSS:',pid=child_pid) + + mem += _VmB('VmRSS:') - since + return mem + #return _VmB('VmRSS:') - since -def stacksize(since=0.0): +def stacksize(since=0.0, children=False): '''Return stack size in bytes. ''' - return _VmB('VmStk:') - since + mem = 0.0 + if children: + for child_pid in all_children(): + mem += _VmB('VmStk:',pid=child_pid) + mem += _VmB('VmStk:') - since + return mem diff --git a/nexus/library/project_manager.py b/nexus/library/project_manager.py index 9d0207009..a4d78ddc9 100644 --- a/nexus/library/project_manager.py +++ b/nexus/library/project_manager.py @@ -100,7 +100,7 @@ class ProjectManager(NexusCore): while len(self.progressing_cascades)>0: elapsed_time = time.time() - start_time self.log('elapsed time %.1f s'%elapsed_time, - ' memory %3.2f MB'%(memory.resident()/1e6), + ' memory %3.2f MB'%(memory.resident(children=True)/1e6), n=1,progress=True) NexusCore.wrote_something = False ipoll+=1