1+ import tracemalloc
12import unittest
23
34from memory_profiler import LineProfiler , profile , show_results
78class TestIncrementDisplay (unittest .TestCase ):
89 """Tests memory incrementation / decrementation display"""
910
11+ def setUp (self ):
12+ tracemalloc .start ()
13+
14+ def tearDown (self ):
15+ tracemalloc .stop ()
16+
1017 def test_loop_count (self ):
1118
1219 def some_loop ():
1320 for i in range (12 ): # line -2
1421 a = 1 # line -1
1522
16- profiler = LineProfiler ()
23+ profiler = LineProfiler (backend = 'tracemalloc' )
1724 wrapped = profiler (some_loop )
1825 wrapped ()
1926 show_results (profiler )
@@ -28,7 +35,7 @@ def test_normal_incr(self):
2835 def normal_incr ():
2936 use_some_memory = [1 ] * (10 ** 6 )
3037
31- profiler = LineProfiler ()
38+ profiler = LineProfiler (backend = 'tracemalloc' )
3239 wrapped = profiler (normal_incr )
3340 wrapped ()
3441
@@ -48,7 +55,7 @@ def loop_incr():
4855 c = [2 ] * (2 * 10 ** 7 ) # line -2
4956 a .append (c )
5057
51- profiler = LineProfiler ()
58+ profiler = LineProfiler (backend = 'tracemalloc' )
5259 wrapped = profiler (loop_incr )
5360 wrapped ()
5461
@@ -64,7 +71,7 @@ def del_stuff():
6471 b = [2 ] * (2 * 10 ** 7 )
6572 del b
6673
67- profiler = LineProfiler ()
74+ profiler = LineProfiler (backend = 'tracemalloc' )
6875 wrapped = profiler (del_stuff )
6976 wrapped ()
7077
@@ -76,6 +83,35 @@ def del_stuff():
7683 self .assertGreater (del_line [1 ], 0 )
7784 self .assertAlmostEqual (- del_line [0 ], b_line [0 ], delta = 1 )
7885
86+ def test_no_false_negative_incr_after_peak_in_loop (self ):
87+ """Regression test for Issue #219 / PR #350.
88+
89+ When a line inside a loop reaches a high memory peak on an early
90+ iteration that is later freed, subsequent iterations of the following
91+ line must compare against the previous line's most recent memory,
92+ not its historical maximum memory (which would accumulate bogus
93+ negative increments on every iteration).
94+ """
95+ def loop_with_early_peak ():
96+ for i in range (5 ):
97+ # Peaks on i == 0 (~150 MiB), small on i > 0
98+ x = [1 ] * (2 * 10 ** 7 if i == 0 else 10 )
99+ y = 1 # Must NOT accumulate a ~-150 MiB decrement on i = 1..4
100+ del x
101+
102+ profiler = LineProfiler (backend = 'tracemalloc' )
103+ wrapped = profiler (loop_with_early_peak )
104+ wrapped ()
105+
106+ show_results (profiler )
107+ measures = list (profiler .code_map .values ())[0 ]
108+ # Ordered lines: for, x = ..., y = 1, del x
109+ y_line = [measures [lineno ] for lineno in sorted (measures )][- 2 ]
110+ y_inc = y_line [0 ]
111+ # Before PR #350, y_inc was around -600 MiB (4 * -150 MiB).
112+ # With PR #350, y = 1 has ~0 MiB increment.
113+ self .assertGreater (y_inc , - 5.0 )
114+
79115
80116if __name__ == '__main__' :
81117 unittest .main ()
0 commit comments