Author: Armin Rigo <ar...@tunes.org> Branch: memory-accounting Changeset: r93275:1cdb7e0ad36b Date: 2017-12-05 19:11 +0100 http://bitbucket.org/pypy/pypy/changeset/1cdb7e0ad36b/
Log: add peak memory usage reporting diff --git a/pypy/module/gc/app_referents.py b/pypy/module/gc/app_referents.py --- a/pypy/module/gc/app_referents.py +++ b/pypy/module/gc/app_referents.py @@ -52,8 +52,10 @@ class GcStats(object): def __init__(self, s): self._s = s - for item in ('total_gc_memory', 'jit_backend_used', 'total_memory_pressure', - 'total_allocated_memory', 'jit_backend_allocated'): + for item in ('total_gc_memory', 'jit_backend_used', + 'total_memory_pressure', + 'total_allocated_memory', 'jit_backend_allocated', + 'peak_memory', 'peak_allocated_memory'): setattr(self, item, self._format(getattr(self._s, item))) self.memory_used_sum = self._format(self._s.total_gc_memory + self._s.total_memory_pressure + self._s.jit_backend_used) @@ -68,21 +70,26 @@ def repr(self): return """Total memory consumed: -GC used: %s +GC used: %s (peak: %s) raw assembler used: %s memory pressure: %s ----------------------------- Total: %s Total memory allocated: -GC allocated: %s +GC allocated: %s (peak: %s) raw assembler allocated: %s memory pressure: %s ----------------------------- Total: %s -""" % (self.total_gc_memory, self.jit_backend_used, self.total_memory_pressure, +""" % (self.total_gc_memory, self.peak_memory, + self.jit_backend_used, + self.total_memory_pressure, self.memory_used_sum, - self.total_allocated_memory, self.jit_backend_allocated, self.total_memory_pressure, + + self.total_allocated_memory, self.peak_allocated_memory, + self.jit_backend_allocated, + self.total_memory_pressure, self.memory_allocated_sum) def get_stats(): diff --git a/pypy/module/gc/referents.py b/pypy/module/gc/referents.py --- a/pypy/module/gc/referents.py +++ b/pypy/module/gc/referents.py @@ -176,6 +176,8 @@ self.total_memory_pressure = rgc.get_stats(rgc.TOTAL_MEMORY_PRESSURE) self.total_gc_memory = rgc.get_stats(rgc.TOTAL_MEMORY) self.total_allocated_memory = rgc.get_stats(rgc.TOTAL_ALLOCATED_MEMORY) + self.peak_memory = rgc.get_stats(rgc.PEAK_MEMORY) + self.peak_allocated_memory = rgc.get_stats(rgc.PEAK_ALLOCATED_MEMORY) self.jit_backend_allocated = jit_hooks.stats_asmmemmgr_allocated(None) self.jit_backend_used = jit_hooks.stats_asmmemmgr_used(None) @@ -184,6 +186,10 @@ cls=W_GcStats, wrapfn="newint"), total_gc_memory=interp_attrproperty("total_gc_memory", cls=W_GcStats, wrapfn="newint"), + peak_allocated_memory=interp_attrproperty("peak_allocated_memory", + cls=W_GcStats, wrapfn="newint"), + peak_memory=interp_attrproperty("peak_memory", + cls=W_GcStats, wrapfn="newint"), total_allocated_memory=interp_attrproperty("total_allocated_memory", cls=W_GcStats, wrapfn="newint"), jit_backend_allocated=interp_attrproperty("jit_backend_allocated", diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py --- a/rpython/memory/gc/incminimark.py +++ b/rpython/memory/gc/incminimark.py @@ -372,6 +372,7 @@ self.old_rawmalloced_objects = self.AddressStack() self.raw_malloc_might_sweep = self.AddressStack() self.rawmalloced_total_size = r_uint(0) + self.rawmalloced_peak_size = r_uint(0) self.gc_state = STATE_SCANNING # @@ -997,6 +998,8 @@ # Record the newly allocated object and its full malloced size. # The object is young or old depending on the argument. self.rawmalloced_total_size += r_uint(allocsize) + self.rawmalloced_peak_size = max(self.rawmalloced_total_size, + self.rawmalloced_peak_size) if alloc_young: if not self.young_rawmalloced_objects: self.young_rawmalloced_objects = self.AddressDict() @@ -1189,6 +1192,19 @@ """ return self.ac.total_memory_alloced + self.rawmalloced_total_size + def get_peak_memory_alloced(self): + """ Return the peak memory ever allocated. The peaks + can be at different times, but we just don't worry for now + """ + return self.ac.peak_memory_alloced + self.rawmalloced_peak_size + + def get_peak_memory_used(self): + """ Return the peak memory GC felt ever responsible for + """ + mem_allocated = max(self.ac.peak_memory_used, + self.ac.total_memory_used) + return mem_allocated + self.rawmalloced_peak_size + def threshold_reached(self, extra=0): return (self.next_major_collection_threshold - float(self.get_total_memory_used())) < float(extra) @@ -2161,6 +2177,8 @@ # size_gc_header = self.gcheaderbuilder.size_gc_header self.rawmalloced_total_size += r_uint(raw_malloc_usage(totalsize)) + self.rawmalloced_peak_size = max(self.rawmalloced_total_size, + self.rawmalloced_peak_size) self.old_rawmalloced_objects.append(arena + size_gc_header) return arena @@ -2929,6 +2947,10 @@ if stats_no == rgc.TOTAL_MEMORY: return intmask(self.get_total_memory_used() + self.nursery_size) + elif stats_no == rgc.PEAK_MEMORY: + return intmask(self.get_peak_memory_used() + self.nursery_size) + elif stats_no == rgc.PEAK_ALLOCATED_MEMORY: + return intmask(self.get_peak_memory_alloced() + self.nursery_size) elif stats_no == rgc.TOTAL_ALLOCATED_MEMORY: return intmask(self.get_total_memory_alloced() + self.nursery_size) elif stats_no == rgc.TOTAL_MEMORY_PRESSURE: diff --git a/rpython/memory/gc/minimarkpage.py b/rpython/memory/gc/minimarkpage.py --- a/rpython/memory/gc/minimarkpage.py +++ b/rpython/memory/gc/minimarkpage.py @@ -140,7 +140,9 @@ # the total memory used, counting every block in use, without # the additional bookkeeping stuff. self.total_memory_used = r_uint(0) + self.peak_memory_used = r_uint(0) self.total_memory_alloced = r_uint(0) + self.peak_memory_alloced = r_uint(0) def _new_page_ptr_list(self, length): @@ -295,6 +297,9 @@ # be a page-aligned address arena_base = llarena.arena_malloc(self.arena_size, False) self.total_memory_alloced += self.arena_size + self.peak_memory_alloced = max(self.total_memory_alloced, + self.peak_memory_alloced) + if not arena_base: out_of_memory("out of memory: couldn't allocate the next arena") arena_end = arena_base + self.arena_size @@ -321,6 +326,8 @@ """Prepare calls to mass_free_incremental(): moves the chained lists into 'self.old_xxx'. """ + self.peak_memory_used = max(self.peak_memory_used, + self.total_memory_used) self.total_memory_used = r_uint(0) # size_class = self.small_request_threshold >> WORD_POWER_2 diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -650,7 +650,8 @@ else: return id(gcref._x) -TOTAL_MEMORY, TOTAL_ALLOCATED_MEMORY, TOTAL_MEMORY_PRESSURE = range(3) +(TOTAL_MEMORY, TOTAL_ALLOCATED_MEMORY, TOTAL_MEMORY_PRESSURE, + PEAK_MEMORY, PEAK_ALLOCATED_MEMORY) = range(5) @not_rpython def get_stats(stat_no): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit