miguelgrinberg/microdot

On ESP32: Out of memory with quite a basic setup?

Closed this issue · 4 comments

Describe the bug

I've installed micropython 1.20 on an Olimex ESP32-POE device. It runs fine. After I established an LAN connection, I just try to import microdot with the following result:

----- main.py -----
>> Trying to import cfg.py: Success
>> Trying to mount SDCard on /flash: Success
machine_id: 240ac49ef998
cpu_freq: 160.0
flash_size: 0x400000
flash_user_start: 0x200000
>> Trying to bring up LAN:
Waiting for IP: . 192.168.13.57
Started webrepl in normal mode
>> Fetching unix time from network: 20230615 12:43:59
Traceback (most recent call last):
File "main.py", line 437, in <module>
MemoryError: memory allocation failed, allocating 2344 bytes
MicroPython v1.20.0 on 2023-04-26; Olimex ESP32 ETH with ESP32

Line 437 is

from microdot import Microdot

To Reproduce

My code looks like this:

# -------- Webserver --------
#import uasyncio
from microdot import Microdot
app = Microdot()
@app.route('/')
def index(request):
    return webpage(cfg)
app.run()

Expected behavior

I wouldn't expect an error just by importing the library..

Thonny tells me that I still have 1.9 MByte "storage" (I think they mean flash), and this is the memory:

>>> micropython.mem_info(0)
stack: 736 out of 15360
GC: total: 111168, used: 75648, free: 35520
No. of 1-blocks: 702, 2-blocks: 85, max blk sz: 264, max free sz: 1045
GC memory layout; from 3ffe4db0:

Is there any chance any of the 436 lines that precede your microdot import are consuming a large part of your memory? You are calling this a "basic setup", but my definition of basic setup would be that you run the web server on its own. These devices have limited resources. If you don't pre-compile your sources, then you must import the largest files first, so that there is more memory available to the compiler. Or else, you should seriously consider pre-compiling, or better yet, freezing as much of your code and libraries as possible.

Thanks for answering so fast...

I had more code working before I encountered this problem. I stripped my code down to basically the minimum. In the 437 lines are functions that are not being used, that makes it so long. I have removed that function now, still with the same result. I even deactivated webrepl.

Could it be that there is a chain of exceptions within your code, each exception consuming heap space or something?

import threading

fails when I try that in the repl

Can I turn on debug somehow? I am not that familiar with micropython yet..

@hagenbuch Most MicroPython ports do not have threading. It is expected for that import to fail. If you are getting any errors, you have to show me the statements that you issued and the errors if you need me to comment on them.

I would suggest that you take hello.py from this repository and save it as your main.py, and see if that works or not. And as I said, if you get any errors, copy the full output here.

See https://microdot.readthedocs.io/en/latest/freezing.html for information on how to cross-compile and/or freeze your application and dependencies to reduce the memory footprint.