echo-lalia/MicroHydra

Display memory allocation failed

Opened this issue · 2 comments

xx21x commented

I'm trying to let the screen display a line of text, and this error message appeared:

MPY: soft reboot
WARNING: Display re-initialized.
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "apps/TMHub/__init__.py", line 6, in <module>
  File "/home/runner/work/MicroHydra/MicroHydra/MicroHydra/CARDPUTER/lib/display/display.py", line 64, in __init__
  File "/home/runner/work/MicroHydra/MicroHydra/MicroHydra/CARDPUTER/lib/display/st7789.py", line 217, in __init__
  File "/home/runner/work/MicroHydra/MicroHydra/MicroHydra/CARDPUTER/lib/display/displaycore.py", line 59, in __init__
MemoryError: memory allocation failed, allocating 64800 bytes

I want to know how to solve this, and better, what caused it and how to prevent it.
Thanks,
Knox

Hello! You're getting an out of memory error when creating a (second) framebuffer.


Full explanation:

The display driver uses a relatively large (compared to the total 512kb of memory) framebuffer to speed up drawing.
The buffer is display_width * display_height * 2 bytes in size, or 64800 bytes on the Cardputer.

Because the buffer is so large, there usually is only enough memory to create one of them, and if you somehow accidentally create a second one, you'll often get a memory error. So, I actually added a little warning in to help diagnose this exact situation!
The WARNING: Display re-initialized. that is printed above your error message means that somehow the Display got created a second time.

Troubleshooting (maybe solution):

You may be calling the Display constructor twice in your code, somewhere. For an extremely simple example:

DISPLAY = display.Display()
DISPLAY = display.Display()

This code will cause that same warning to be printed (and may, or may not, cause the same memory error).
Try to see if you're re-creating the display object anywhere in your code.

If you're using any of the built-in MicroHydra modules that draw to the display, there's also a chance that the display is being created somewhere in the module's code, and then you're re-creating the display afterwards. (This shouldn't be happening. So if that is what's going on, I'll need to patch that out!). You can try moving your Display initialization code above any other code in your app (before the creation/initialization of any other objects), to see if that's whats going on.

Hey, just to update you (or anyone else who finds this) about potential solutions:

I recently encountered this error in a novel way. I was editing the main script for an app that had multiple files (An import-able directory with an __init__.py, and a few other files, but the main logic was inside a single, other, .py file).

When I tried hitting F5 in Thonny to test the script, I would get the WARNING: Display re-initialized. error (and then usually an out-of-memory error).

I realized, in this case, this was happening because the file was being imported/run twice. The __init__.py file had a non-specific try:... except:... statement to import from multiple locations, and when an unrelated error would be encountered in the script, it would be caught by the try/except block, and would import the script a second time. The second time, it would run out of memory, so I would never see the actual error that caused it to fail the first time. I replaced the except: with an except: ImportError to fix this specific variant of this issue :)