"Not enough heap memory"


Author Message
bfwolf
Senior Member

Joined: 03/01/2025
Location: Germany
Posts: 243
Posted: 09:39pm 02 Apr 2026      

  matherp said  When PSRAM is enabled there are two heap memory pools. One in main RAM and one in PSRAM. For performance reasons internal functions that use memory always only use normal RAM so in your example calling a subroutine needs memory and always gets it from the normal ram pool. Variable memory usage will first try to use normal RAM as it is faster and if not enough is available will then use PSRAM. It will automatically use PSRAM for a variable if the request for memory is more than half the size of the RAM pool (i.e. big arrays).
You have created an edge case. You have lots of relatively small variables that are filling the heap in normal RAM and not triggering the condition that places them in PSRAM. Then when the system needs RAM for internal use there isn't any hence the error.
I can't see an easy solution that is performant. The obvious answer would be to place variables in PSRAM if the heap in normal ram falls below a certain level. The problem with this is that calling the routine to calculate how much normal ram is left would massively slow down variable creation. This wouldn't matter too much for global variables but would be a disaster for local variables.


I've been thinking about your dilemma regarding RAM usage, and the following idea came to me:

Why not consider a directive that allows you to control RAM priority from within the program? In other words, make the priority of using fast internal RAM and slow QSPI RAM controllable for subsequent DIM commands?

This could be done e.g. using an OPTION that would be valid for all DIM commands until the "opposite" OPTION is used.

For example:
OPTION RAMPRIORITY [FASTRAM | SLOWRAM]


Instead of controlling it via OPTION, you could also introduce true directives, similar to how it's done in Turbo Pascal/Delphi: through a "special syntax" of comments. This would have the advantage of being compatible with other BASIC dialects.

I did some research: The FreeBasic compiler also does something similar using "meta-commands" that begin with the 2-character-sequence '$ . I assume that FreeBasic additionally expects the sequence '$ to be at the beginning of a line (i.e. the first non-whitespace position).

https://www.freebasic.net/wiki/CatPgCompilerSwitches

There are then meta-commands like '$DYNAMIC, '$LANG, etc.

Following this scheme, one could, for example, introduce the meta-commands
'$RAMPRIORITY FASTRAM
and
'$RAMPRIORITY SLOWRAM

in MMBasic.

I wouldn't bring the term PSRAM into this context, because that would be too specifically tailored to microcontrollers with PSRAM. And slow external RAMs with different interfaces are also common in other controllers.

How do you think about it?

Regards, bfwolf.