def _get_summaries(function, *args): """Get a 2-tuple containing one summary from before, and one summary from after the function has been invoked. """ s_before = summary.summarize(get_objects()) function(*args) s_after = summary.summarize(get_objects()) return (s_before, s_after)
def create_summary(self): """Return a summary. See also the notes on ignore_self in the class as well as the initializer documentation. """ if not self.ignore_self: res = summary.summarize(muppy.get_objects()) else: # If the user requested the data required to store summaries to be # ignored in the summaries, we need to identify all objects which # are related to each summary stored. # Thus we build a list of all objects used for summary storage as # well as a dictionary which tells us how often an object is # referenced by the summaries. # During this identification process, more objects are referenced, # namely int objects identifying referenced objects as well as the # correspondind count. # For all these objects it will be checked wether they are # referenced from outside the monitor's scope. If not, they will be # subtracted from the snapshot summary, otherwise they are # included (as this indicates that they are relevant to the # application). all_of_them = [] # every single object ref_counter = {} # how often it is referenced; (id(o), o) pairs def store_info(o): all_of_them.append(o) if id(o) in ref_counter: ref_counter[id(o)] += 1 else: ref_counter[id(o)] = 1 # store infos on every single object related to the summaries store_info(self.summaries) for k, v in self.summaries.items(): store_info(k) summary._traverse(v, store_info) # do the summary res = summary.summarize(muppy.get_objects()) # remove ids stored in the ref_counter for _id in ref_counter: # referenced in frame, ref_counter, ref_counter.keys() if len(gc.get_referrers(_id)) == (3): summary._subtract(res, _id) for o in all_of_them: # referenced in frame, summary, all_of_them if len(gc.get_referrers(o)) == (ref_counter[id(o)] + 2): summary._subtract(res, o) return res
def print_diff(self, ignore=[]): """Print the diff to the last time the state of objects was measured. keyword arguments ignore -- list of objects to ignore """ # ignore this and the caller frame ignore.append(inspect.currentframe()) #PYCHOK change ignore diff = self.get_diff(ignore) print("Added objects:") summary.print_(summary.summarize(diff['+'])) print("Removed objects:") summary.print_(summary.summarize(diff['-'])) # manual cleanup, see comment above del ignore[:]
def test_sweep(self): """Test that all and only empty entries are removed from a summary.""" objects = ['the', 'quick', 'brown', 'fox', 1298, 123, 234, [], {}] summ = summary.summarize(objects) # correct removal of rows when sizes are empty summary._subtract(summ, {}) summary._subtract(summ, []) summ = summary._sweep(summ) found_dict = found_tuple = False for row in summ: if row[0] == "<type 'dict'>": found_dict = True if row[0] == "<type 'tuple'>": found_tuple = True self.assert_(found_dict == False) self.assert_(found_tuple == False) # do not remove row if one of the sizes is not empty # e.g. if the number of objects of a type did not change, but the # total size did summ = summary._subtract(summ, 'the') summ = summary._subtract(summ, 'quick') summ = summary._subtract(summ, 'brown') summ = summary._subtract(summ, '42') summ = summary._sweep(summ) found_string = False for row in summ: if row[0] == summary._repr(''): found_string = True self.assert_(row[1] == 0) totalsize = _getsizeof('fox') - _getsizeof('42') self.assert_(row[2] == totalsize) self.assert_(found_string == True)
def test_summarize(self): """Test summarize method. """ objects = [1, 'a', 'b', 'a', 5, [], {}] expected = [[summary._repr(''), 3, 3*_getsizeof('a')],\ [summary._repr(1), 2, 2*_getsizeof(1)],\ [summary._repr([]), 1, _getsizeof([])],\ [summary._repr({}), 1, _getsizeof({})]] res = summary.summarize(objects) for row_e in res: self.assert_(row_e in expected)
def __init__(self, ignore_self=True): """Constructor. The number of summaries managed by the tracker has an performance impact on new summaries, iff you decide to exclude them from further summaries. Therefore it is suggested to use them economically. Keyword arguments: ignore_self -- summaries managed by this object will be ignored. """ self.s0 = summary.summarize(muppy.get_objects()) self.summaries = {} self.ignore_self = ignore_self
def process_response(self, request, response): req = request.META['PATH_INFO'] if req.find('site_media') == -1: print req self.end_objects = muppy.get_objects() sum_start = summary.summarize(self.start_objects) sum_end = summary.summarize(self.end_objects) diff = summary.get_diff(sum_start, sum_end) summary.print_(diff) #print '~~~~~~~~~' #cb = refbrowser.ConsoleBrowser(response, maxdepth=2, str_func=output_function) #cb.print_tree() print '~~~~~~~~~' a = asizeof(response) print 'Total size of response object in kB: %s' % str(a / 1024.0) print '~~~~~~~~~' a = asizeof(self.end_objects) print 'Total size of end_objects in MB: %s' % str(a / 1048576.0) b = asizeof(self.start_objects) print 'Total size of start_objects in MB: %s' % str(b / 1048576.0) print '~~~~~~~~~' return response
def process_response(self, request, response): req = request.META['PATH_INFO'] if req.find('site_media') == -1: print req self.end_objects = muppy.get_objects() sum_start = summary.summarize(self.start_objects) sum_end = summary.summarize(self.end_objects) diff = summary.get_diff(sum_start, sum_end) summary.print_(diff) #print '~~~~~~~~~' #cb = refbrowser.ConsoleBrowser(response, maxdepth=2, str_func=output_function) #cb.print_tree() print '~~~~~~~~~' a = asizeof(response) print 'Total size of response object in kB: %s' % str(a/1024.0) print '~~~~~~~~~' a = asizeof(self.end_objects) print 'Total size of end_objects in MB: %s' % str(a/1048576.0) b = asizeof(self.start_objects) print 'Total size of start_objects in MB: %s' % str(b/1048576.0) print '~~~~~~~~~' return response
def test_subtract(self): """Test that a single object's data is correctly subtracted from a summary. - result in correct total size and total number of objects - if object was not listed before, it should be listed negative afterwards """ objects = ['the', 'quick', 'brown', 'fox', 1298, 123, 234, [], {}] summ = summary.summarize(objects) summary._subtract(summ, 'the') summary._subtract(summ, {}) summary._subtract(summ, (1,)) # to verify that these rows where actually included afterwards checked_str = checked_dict = checked_tuple = False for row in summ: if row[0] == summary._repr(''): totalsize = _getsizeof('quick') + _getsizeof('brown') +\ _getsizeof('fox') self.assert_(row[1] == 3, "%s != %s" % (row[1], 3)) self.assert_(row[2] == totalsize, totalsize) checked_str = True if row[0] == summary._repr({}): self.assert_(row[1] == 0) self.assert_(row[2] == 0) checked_dict = True if row[0] == summary._repr((1,)): self.assert_(row[1] == -1) self.assert_(row[2] == -_getsizeof((1,))) checked_tuple = True self.assert_(checked_str, "no str found in summary") self.assert_(checked_dict, "no dict found in summary") self.assert_(checked_tuple, "no tuple found in summary") summary._subtract(summ, 'quick') summary._subtract(summ, 'brown') checked_str = False for row in summ: if row[0] == summary._repr(''): self.assert_(row[1] == 1) self.assert_(row[2] == _getsizeof('fox')) checked_str = True self.assert_(checked_str, "no str found in summ")
if __name__=='__main__': initialize() tr = tracker.SummaryTracker() run(title) close() #profile.run("run_same(store, 5)", filename='vslib.profile') tr.print_diff() #p = pstats.Stats('vslib.profile') #p.sort_stats('cumulative').print_stats(20) if 0: objects = muppy.get_objects(include_frames=True) print muppy.get_size(objects) sum1 = summary.summarize(objects) summary.print_(sum1) if 0: root = '' ib = refbrowser.InteractiveBrowser(root) ib.main() if 1: import objgraph, inspect objgraph.show_most_common_types(limit=30) if objgraph.count('document') > 0: print 'document:', objgraph.count('document') docs = objgraph.by_type('document') d = docs[0] objgraph.show_backrefs(docs, max_depth=10) #chain = objgraph.find_backref_chain(d, inspect.ismodule) #in_chain = lambda x, ids=set(map(id, chain)): id(x) in ids