sco1 / skyportal

A PyPortal based flight tracker
MIT License
1 stars 0 forks source link

Memory Error while taking screenshots #11

Closed sco1 closed 1 year ago

sco1 commented 1 year ago

At some point recently I seemed to have broken the screenshotting capability:

Traceback (most recent call last):
  File "code.py", line 81, in <module>
  File "skyportal/displaylib.py", line 534, in process_touch
  File "skyportal/displaylib.py", line 171, in check_fire
  File "skyportal/displaylib.py", line 94, in take_screenshot
  File "adafruit_bitmapsaver.py", line 161, in save_pixels
  File "adafruit_bitmapsaver.py", line 159, in save_pixels
  File "adafruit_bitmapsaver.py", line 107, in _write_pixels
MemoryError: memory allocation failed, allocating 2048 bytes

Checking the memory stats before saving the bitmap seems to show there's plenty of memory left, even before manually GCing:

Free 23408 Alloc 192976
GC Free 25232 Alloc 191152

So I'm not sure where the issue lies.

sco1 commented 1 year ago

We start to run into memory errors after f80fe457adb3db13a63fbd71eda748748a479b77 Commenting out the info box initialization seems to solve the problem.

Checking on the memory usage right before we try to save the screenshot with 20 aircraft on screen:

With info box init: Pre SS Free 24960 Alloc 191936
No info box init:   Pre SS Free 50288 Alloc 166608
sco1 commented 1 year ago

This seems to be more of a general issue than I realized, since we're no longer able to save the map tiles either. I just discovered this guide that I'll give a read through and see if I can make some changes to alleviate all of these problems.

For now it seems like I can still get screenshots taken most of the time if I just call it manually and not load the buttons. It will still occasionally fail but gets there eventually.

Will keep this comment edited with tracing below.

After changing some of the imports, namely datetime to not import the whole module.

code.py imports:

pre import alloc:   4288, free: 212096
math       alloc:   4416, free: 211968
datetime   alloc:  30912, free: 185472
pyportal   alloc:  87808, free: 128576
displaylib alloc: 131312, free:  85072
maplib     alloc: 131440, free:  84944
opensky    alloc: 143216, free:  73168
secrets    alloc: 143344, free:  73040
constants  alloc: 143456, free:  72928

displaylib imports:

pre import   alloc: 103424, free: 113216
math         alloc: 103536, free: 113104
os           alloc: 103664, free: 112976
collections  alloc: 103792, free: 112848
datetime     alloc: 103936, free: 112704
touchscreen  alloc: 102016, free: 114624
board        alloc: 102144, free: 114496
displayio    alloc: 102256, free: 114384
terminalio   alloc: 102384, free: 114256
bitmapsaver  alloc: 104064, free: 112576
roundrect    alloc: 106720, free: 109920
labels       alloc: 107152, free: 109488
functools    alloc: 108320, free: 108320
aircraftlib  alloc: 130144, free:  86496
maplib       alloc: 133648, free:  82992
config       alloc: 133840, free:  82800

Tracing initialization

Pre ui init    alloc: 146944, free: 69440
Post ui init   alloc: 167840, free: 48544
Post wifi      alloc: 182480, free: 33904
Post time get  alloc: 172000, free: 44384
After bbox     alloc: 172144, free: 44240
After 2nd init alloc: 173008, free: 43376
After opensky  alloc: 179168, free: 37216

So before we even hit the main loop we've allocated more than 75% of our RAM.

Looks like the biggest offenders are pyportal, displaylib, aircraftlib, and datetime. I don't think we can do much about pyportal, could do some things about datetime but I'm not at the point where I want to deal with time myself yet.

sco1 commented 1 year ago

With 912297ec30015672bcf2e7b48b2810d97216c1f3 this might possibly be fixed? It seems to work ok now but with OpenSky currently down I can't test with aircraft on screen.

sco1 commented 1 year ago

I've decided to fix this by just removing the screenshot UI altogether for the next release 😄

With the memory constraints everywhere else it ended up being easier to not have to worry about the additional UI overhead for something that's mostly used to debug. If I need to do that I can just edit in the line of code to do so.