When your project gets more complex, you can run into an error message of “Memory allocation failed”.  This indicates that the memory manager (even after garbage collection) did not find a large enough continuous space in volatile memory to store a newly created variable. Eventually your project may become sufficiently complex that it will require additional RAM by upgrading to a different microcontroller board. However before upgrading, there are numerous techniques worth evaluating that can reduce your memory footprint and provide larger open memory spaces for your project.

Measure measurement tools

To find a good solution to reduce memory use, it’s best to identify what parts of your code use the most memory. Break your code into sections and use the combination of gc.collect() and printing gc.mem_free() to identify how much memory is used in each section. Pay particular attention to any graphics, font files or text labels since they tend to be heavy users of memory.

Use gc.collect() and gc.mem_free(): The gc library also contains a function called gc.mem_free() that returns the value of free memory bytes. The gc.mem_free() command returns the value of free memory that the memory manager sees. The command gc.mem_free() thinks that “phantom” variables are using space, so it only counts totally-free space. 

Important: The command gc.mem_free() only counts free bytes of RAM. Always run gc.collect()  first so you clean out any garbage “phantom” items before calling gc.mem_free().  That way you know exactly how much memory is really available for your projects. 

When you want to check how much RAM your code is using, bracket your code with these gc library commands to measure your available memory and then calculate the amount of bytes that were used by a code section. You can also measure how much memory is used by your imports the same way. 

Here is a code snippet to quantify how many bytes of RAM are used by a code section. 

import gc
# add other imports

gc.collect()
start_mem = gc.mem_free()
print( "Point 1 Available memory: {} bytes".format(start_mem) ) 

# add code here to be measured for memory use

gc.collect()
end_mem = gc.mem_free()

print( "Point 2 Available memory: {} bytes".format(end_mem) )
print( "Code section 1-2 used {} bytes".format(start_mem - end_mem) )

Measuring your code’s memory usage is the first step to decide where to focus your improvements. The next section describes specific situations and techniques to help you get your projects running when you encounter memory limits on your board. 

This guide was first published on Apr 17, 2021. It was last updated on Apr 17, 2021.

This page (Memory: Measuring memory use) was last updated on May 10, 2021.

Text editor powered by tinymce.