0

I have written a small MicroPython program for raspberry PI Pico.

This program creates a thread which increments a counter and prints the value in hex.

import _thread

def myThread():
    count = 0
    while True:
        count = count + 1
        print(hex(count))

_thread.start_new_thread(myThread, ())

This program always fails at 0x16ea.

If I do not use the hex function the code works fine.

A bit of digging using micropython.mem_info() and it looks like the hex function has a memory leak. Or am I doing something wrong?

Raphael
  • 517
  • 4
  • 18
Tom Martin
  • 1,227
  • 2
  • 10
  • 17

2 Answers2

1

I saw the same result when running your program on a PICO with MicroPython v1.17-59-g782d5b2e5-dirty that I compiled. The program runs, prints a couple of garbage characters and stops around the same value. I recompiled MicroPython with #define MICROPY_PY_BUILTINS_STR_OP_MODULO (0) set in mpconfigport.h to disable the builtin hex.

Running the program now results in:

Unhandled exception in thread started by <function myThread at 0x20009810>
Traceback (most recent call last):
  File "test.py", line 8, in myThread
MemoryError: memory allocation failed, allocating 0 bytes

Line 8 is the print(hex(count)) line. The hex method allocates some memory for the new string object it returns, MicroPython does not do automatic garbage collection in threads.

If you modify your program to gc.collect() before running out of memory the program runs without stopping

import gc
import _thread

def myThread():
    count = 0
    while True:
        count = count + 1
        print(hex(count))

        if (count % 1000 == 0):
            gc.collect()

_thread.start_new_thread(myThread, ())
Russ Hughes
  • 175
  • 7
1

I've raised https://github.com/micropython/micropython/issues/7981 to investigate this, with a smaller repro that doesn't use hex.

Small correction to Russ's answer above, automatic collection should occur in threads (and it's actually happening in this example) -- there's specific code in the rp2040 port to handle collection regardless of which thread triggered it.