Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    How do I diagnose MemoryError?

    Scheduled Pinned Locked Moved Getting Started
    memoryerror
    18 Posts 2 Posters 4.7k Views 2 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B Offline
      BetterAuto Pybytes Beta
      last edited by BetterAuto

      Need help diagnosing this. I have nothing in boot.py or main.py.

      The err.py and data_store.py modules have been tested individually and did not throw any MemoryErrors. The err.py module captures error messages and stores them via data_store.py to my server if available, or on the local filesystem if the server is not available, for sending at the next opportunity. When testing err.py I necessarily had to also test data_store.py.

      What should my next steps be?

      >>> mem_info()
      stack: 736 out of 7168
      GC: total: 67008, used: 7616, free: 59392
       No. of 1-blocks: 23, 2-blocks: 6, max blk sz: 384, max free sz: 3702
      >>> import test_motor
      Starting test_motor
      [SUCCESS] motor.voltage
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "test_motor.py", line 19, in <module>
        File "motor.py", line 51, in run
        File "err.py", line 17, in __init__
        File "data_store.py", line 23, in __init__
      MemoryError:
      >>> mem_info()
      MemoryError
      >>>
      
      1 Reply Last reply Reply Quote 0
      • B Offline
        BetterAuto Pybytes Beta
        last edited by

        Confirmed that the problem is in err.py and/or data_store.py. Commented it out and no more MemoryError. But how to troubleshoot those, I don't know. As mentioned, those don't error when tested directly.

        robert-hhR 1 Reply Last reply Reply Quote 0
        • robert-hhR Offline
          robert-hh @BetterAuto
          last edited by

          @betterauto Your code probably simply runs out of heap space.
          And that happens in the creation of class instances. You should look if you create these instances once or repeatedly. If once, look how much memory they allocate and try to reduce that. If repeatedly, try to insert gc.collect() before creating the class instances.
          Otherwise, you can save a lot or RAM by putting known working modules into frozen bytecode, at which point their code does not use RAM any more, at the penalty of a few percent slower execution.

          1 Reply Last reply Reply Quote 1
          • B Offline
            BetterAuto Pybytes Beta
            last edited by

            How do I determine how much memory they use? What commands?

            robert-hhR 1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @BetterAuto
              last edited by

              @betterauto You can use gc.mem_free() or gc.mem_alloc() to look at the change in allocation before after some activities. That's a roigh indication. It can still happen that even if mem_free() shows sufficient memory, you cannot allocate a large buffer because that free memory is fragmented. gc.collect() can be used to force garbage collection, which often helps.

              1 Reply Last reply Reply Quote 1
              • B Offline
                BetterAuto Pybytes Beta
                last edited by

                I do gc.collect() often but for some reason was not doing so inside this module. I'll try that. Good info on the other gc functions, will try those.

                1 Reply Last reply Reply Quote 0
                • B Offline
                  BetterAuto Pybytes Beta
                  last edited by

                  Getting the same error in a different module but this one uses copious gc.collect(). I am at a loss what to do next. Frozen bytecode? Move to a different platform? Suggestions appreciated.

                  This module tests my update functionality. The updates module downloads either new system files or new data files. It uses the cloud module, which in turn uses the mqtt module, which in turn uses the Adafruit robust MQTT client. Too many modules?

                  I edited the Adafruit module to run gc.collect() very frequently, almost every other line.

                  You can see from running gc.collect() manually on the REPL that it doesn't free much. But why would running it there make any difference if I am also running it copiously within the code?

                  Frustrating.

                  >>> import test_updates
                  Starting test_updates
                  Traceback (most recent call last):
                    File "<stdin>", line 1, in <module>
                    File "test_updates.py", line 9, in <module>
                    File "updates.py", line 7, in <module>
                    File "cloud.py", line 4, in <module>
                    File "mqtt.py", line 12, in <module>
                    File "umqtt/robust.py", line 7, in <module>
                  MemoryError: memory allocation failed, allocating 82 bytes
                  >>> import gc
                  >>> gc.mem_free()
                  18688
                  >>> gc.mem_alloc()
                  48432
                  >>> gc.collect()
                  >>> gc.mem_free()
                  19808
                  >>> gc.mem_alloc()
                  47280
                  >>>
                  
                  robert-hhR 1 Reply Last reply Reply Quote 0
                  • robert-hhR Offline
                    robert-hh @BetterAuto
                    last edited by

                    @betterauto Frozen bytecode is it. gc.collect() won't change anything, if the majority of RAm is used by bytecode. Frozen bytecode moves that to flash.

                    1 Reply Last reply Reply Quote 1
                    • B Offline
                      BetterAuto Pybytes Beta
                      last edited by BetterAuto

                      Cool thanks for the rapid reply. Do you have a link for a handy guide for doing this? Edit: This looks good:
                      https://learn.adafruit.com/micropython-basics-loading-modules/frozen-modules

                      robert-hhR 2 Replies Last reply Reply Quote 0
                      • robert-hhR Offline
                        robert-hh @BetterAuto
                        last edited by robert-hh

                        @betterauto It's not difficult, but uses a few steps, which may fail. But once you succeded, thigns get much more convenient.
                        You have to set-up your own build environment.
                        a) clone this repository https://github.com/pycom/pycom-micropython-sigfox
                        b) follow the instructions in https://github.com/pycom/pycom-micropython-sigfox/README.md, section ESP32 (not Pyboard)
                        c) Once you've cloned it, goto your_path_to_the_clone/pycom-micropython-sigfox/esp32 and follow the instructions in the esp32/README.md. That includes the cloning of another repository, https://github.com/pycom/pycom-esp-idf
                        d) once you have set-up everything, you'll end up using make for everything:

                        • cleaning: make clean
                        • build bootloader: make TARGET=boot
                        • build for WIPY: make BOARD=WIPY
                        • build for LOPY, make BOARD=LOPY LORA_BAND = USE_BAND_868
                        • upload firmware: make flash (needs jumper G23->GND too, unless you use a non-Pycom board)
                        • erase board: make erase

                        The best environment for that is Linux. Some people use OS X too
                        Scripts to go into frozen bytecode have to be placed in the esp32/frozen directory. by default, this directory only contains _boot.py. Then run make and make flash.
                        The binaries built during that process are in esp32/build/xxPY/release/appimg.bin. That file can be upload by OTA too.

                        B 1 Reply Last reply Reply Quote 1
                        • B Offline
                          BetterAuto Pybytes Beta
                          last edited by

                          Excellent, thanks. Will try to grok this when I'm more awake.

                          In the interim I also will trim down the modules to the barest minimum to test the functionality I'm after, then will port the code fixes into the fuller modules, freeze the code, and viola. That way I'm not taking a lot of extra time to recompile the image every time just to debug some functionality.

                          1 Reply Last reply Reply Quote 0
                          • robert-hhR Offline
                            robert-hh @BetterAuto
                            last edited by

                            @betterauto The adafruit link is for esp8266. For Pycom esp32, the method is the same, just another directory. And obviously you can put stable modules in frozen bytecode, and the ones in progress in RAM. The code looks the same.

                            1 Reply Last reply Reply Quote 1
                            • B Offline
                              BetterAuto Pybytes Beta
                              last edited by

                              Robert rather than compile into the flash can I use .mpy files instead? I read somewhere that WiPy runs everything out of RAM, even frozen bytecode. I found your mpy compiler:
                              https://forum.micropython.org/viewtopic.php?t=2299

                              robert-hhR 1 Reply Last reply Reply Quote 0
                              • robert-hhR Offline
                                robert-hh @BetterAuto
                                last edited by robert-hh

                                @betterauto You can do so, but that only helps if you run into memory problems during import. If you use the compilers from my repository, be awary that the versions for micropython.org and pycom.io are different. Let me update the pycom.io version.

                                Edit: Updated. May not have been necessary.

                                B 1 Reply Last reply Reply Quote 1
                                • B Offline
                                  BetterAuto Pybytes Beta @robert-hh
                                  last edited by

                                  @robert-hh looking at the test_updates error I pasted earlier is that an error on import do you think? Not sure how to tell the difference.

                                  robert-hhR 1 Reply Last reply Reply Quote 0
                                  • robert-hhR Offline
                                    robert-hh @BetterAuto
                                    last edited by

                                    @betterauto Import error happen at the import statement. so if File "umqtt/robust.py", line 7, in <module> is an import statement, the pre-compiling can help.

                                    1 Reply Last reply Reply Quote 1
                                    • B Offline
                                      BetterAuto Pybytes Beta
                                      last edited by

                                      MOST helpful. How can I thank you beyond upvoting your replies?

                                      1 Reply Last reply Reply Quote 0
                                      • B Offline
                                        BetterAuto Pybytes Beta @robert-hh
                                        last edited by

                                        @robert-hh said in How do I diagnose MemoryError?:

                                        b) follow the instructions in https://github.com/pycom/pycom-micropython-sigfox/README.md, section ESP32 (not Pyboard)

                                        Correct URL
                                        https://github.com/pycom/pycom-micropython-sigfox/blob/master/README.md

                                        1 Reply Last reply Reply Quote 0

                                        Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                        Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                        With your input, this post could be even better 💗

                                        Register Login
                                        • 1 / 1
                                        • First post
                                          Last post

                                        Pycom on Twitter

                                        Pycom