scd30 icon indicating copy to clipboard operation
scd30 copied to clipboard

Memory Leak calling #get_data_ready

Open mankyd opened this issue 3 years ago • 0 comments

Calling sensor.get_data_ready() in a loop causes a slow memory leak. It gets worse if periodic measurement is enabled.

import time
import tracemalloc

from scd30_i2c import SCD30

def print_trace_diff(a, b):
    stats = [s for s in b.compare_to(a, 'lineno') if not s.traceback[0].filename.endswith('tracemalloc.py')]
    stats = [s for s in stats if s.size_diff != 0]                                                                                                                                                                                                                                                                                                                                                      

    if stats:
        for stat in stats[:10]:
            print(stat)                                                                                                                                                                                                                                                                                                                       


def main():
    tracemalloc.start(10)
    snap = tracemalloc.take_snapshot()

    scd30 = SCD30()

    #scd30.set_measurement_interval(5)                                                                                                                                                                                                                                                                                                                                                                                                  
    #scd30.start_periodic_measurement()                                                                                                                                                                                                                                                                                                                                                                                                 
    try:
        while True:
            print("ready: ", scd30.get_data_ready())
            time.sleep(5)
            print_trace_diff(snap, tracemalloc.take_snapshot())
            print()
    except KeyboardInterrupt:
#        scd30.stop_periodic_measurement()                                                                                                                                                                                                                                                                                                                                                                                              
        scd30.soft_reset()


if __name__ == '__main__':
    main()

The first print looks something like:

ready:  0
/usr/lib/python3.7/ctypes/__init__.py:60: size=1332 B (+1332 B), count=20 (+20), average=67 B
/usr/lib/python3.7/ctypes/__init__.py:55: size=1288 B (+1288 B), count=19 (+19), average=68 B
/home/dave/project/lib/python3.7/site-packages/smbus2/smbus2.py:252: size=1242 B (+1242 B), count=17 (+17), average=73 B
/usr/lib/python3.7/enum.py:892: size=936 B (+936 B), count=26 (+26), average=36 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:174: size=780 B (+780 B), count=2 (+2), average=390 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:136: size=720 B (+720 B), count=3 (+3), average=240 B
/usr/lib/python3.7/logging/__init__.py:2003: size=404 B (+404 B), count=1 (+1), average=404 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:153: size=372 B (+372 B), count=1 (+1), average=372 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:131: size=364 B (+364 B), count=1 (+1), average=364 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:121: size=364 B (+364 B), count=1 (+1), average=364 B

By the time its run a few times, you can see a steady increase in the number of objects allocated by the library:

/usr/lib/python3.7/ctypes/__init__.py:60: size=1484 B (+1484 B), count=23 (+23), average=65 B
/usr/lib/python3.7/ctypes/__init__.py:55: size=1440 B (+1440 B), count=22 (+22), average=65 B
/home/dave/project/lib/python3.7/site-packages/smbus2/smbus2.py:252: size=1394 B (+1394 B), count=20 (+20), average=70 B
/usr/lib/python3.7/enum.py:892: size=936 B (+936 B), count=26 (+26), average=36 B
############## Steady, monotonic increase on line 136 below 
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:136: size=864 B (+864 B), count=7 (+7), average=123 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:174: size=780 B (+780 B), count=2 (+2), average=390 B
/usr/lib/python3.7/logging/__init__.py:2003: size=404 B (+404 B), count=1 (+1), average=404 B
/home/dave/project/lib/python3.7/site-packages/scd30_i2c/__init__.py:153: size=372 B (+372 B), count=1 (+1), average=372 B=

mankyd avatar Mar 11 '22 19:03 mankyd