[pypy-commit] pypy memory-accounting: add peak memory usage reporting
arigo
pypy.commits at gmail.com
Tue Dec 5 13:13:01 EST 2017
Author: Armin Rigo <arigo at 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):
More information about the pypy-commit
mailing list