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 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_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 _get_usage(function, *args): """Get the usage of a function call. This function is to be used only internally. The 'real' get_usage function is a wrapper around _get_usage, but the workload is done here. """ res = [] # init before calling (s_before, s_after) = _get_summaries(function, *args) # ignore all objects used for the measurement ignore = [] if s_before != s_after: ignore.append(s_before) for row in s_before: # ignore refs from summary and frame (loop) if len(gc.get_referrers(row)) == 2: ignore.append(row) for item in row: # ignore refs from summary and frame (loop) if len(gc.get_referrers(item)) == 2: ignore.append(item) for o in ignore: s_after = summary._subtract(s_after, o) res = summary.get_diff(s_before, s_after) return summary._sweep(res)
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")
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")