I'm trying to chase down a memory leak in a python 3.6 program.
For that I'm testing tracemalloc, which allows me to compare memory snapshots and print out a "backtrace".
The max number of frames in the backtrace should be set as the first argument to tracemalloc.start(), according to the docs.
However, in my minimal test setup (code below) I start tracemalloc with argument 25, but I only get 1 frame in the backtrace, where I would expect 2:
me@my_machine:/tmp$ python ./test_tm.py
Entry: /tmp/test_tm_utils.py:2: size=3533 KiB (+3533 KiB), count=99746 (+99746), average=36 B
Traceback:
/tmp/test_tm_utils.py:2
I would expect two lines, like so:
Entry: /tmp/test_tm_utils.py:2: size=3533 KiB (+3533 KiB), count=99746 (+99746), average=36 B
Traceback:
/tmp/test_tm_utils.py:2
/tmp/test_tm.py:10
^^^^^^^^^^^^^^^^^^
Main program in _/tmp/test_tm.py_:
import tracemalloc
tracemalloc.start(25)
import test_tm_utils
if __name__ == '__main__':
s1 = tracemalloc.take_snapshot()
test_tm_utils.myfun()
s2 = tracemalloc.take_snapshot()
diff = s2.compare_to(s1, 'lineno')
for entry in diff[:1]:
print('\nEntry: {}'.format(entry))
print('Traceback:')
for line in entry.traceback:
print(' {}'.format(line))
And the memory leak function in test_tm_utils.py:
def myfun(lst=list()):
lst.append([i for i in range(100000)])
The secret is the key_type parameter. You must use the value "traceback" to get all the lines specified in tracemalloc.start(). If you use "lineno" or "filename" you only get one line.
This is true for both Statistics or in your case compare_to.
So your code should look something like this:
s2 = tracemalloc.take_snapshot()
diff = s2.compare_to(s1, 'traceback') # This is the only change
for entry in diff[:1]:
print('\nEntry: {}'.format(entry))
print('Traceback:')
for line in entry.traceback:
print(' {}'.format(line))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With