How much free memory is actually needed?

Hi, I've just upgraded from version 1.0 to 1.6.5 (probably ought to have done this years ago!)

I have a mini-pro project that used to compile, upload and run without problems. Since upgrading to 1.6.5 I get this error message....

Sketch uses 28,716 bytes (93%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,862 bytes (90%) of dynamic memory, leaving 186 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

First question - I assume the fact that program memory storage is nearly full is NOT something that should in itself effect stability? I assume I need to be focusing on dynamic memory instead?

Second question - how much dynamic memory should I be aiming for? If I only need another 5% then it probably worth my while to trawl through a couple of dozen libraries looking to save a few bytes here and there, but if I realistically need to have (say) 65% free dynamic memory, then I might as well just upgrade to a different flavour of arduino.

P.S. everything is already written to progmem whenever possible!

If you post your code, we might be able to figure out a different way of doing things. Tough to do without seeing your code.

Tough to do without seeing your code.

I know ‘show us your code’ is a standard response, but I’m NOT asking for a code fix! I’m asking for some guidance about how much free memory is actually required!

My project consists of a dozen different libraries, so I wouldn’t expect anyone to start downloading dozens of files and trawling through 1000s of lines of code for me! ( but thanks for the offer anyway :slight_smile:

You need free “dynamic” memory for two things:

  1. Stack space. How much you need is determined by the maximum call depth (functions calling other functions, interrupt handlers calling functions, etc.), and the amount of stack space required by the local variables of those functions and interrupt handlers.

  2. Dyanmically-created objects. i.e. - objects created at run-time using “new” or any other operation that mallocs heap memory.

If the worst case memory use EVER exceeds, by even a single byte, the amount of physical memory present, it is very likely bad things will happen. For all but the simplest of applications, the exact maximum RAM usage is largely un-knowable, but must instead be estimated, and a generous “safety margin” applied to account for black swan events.

Ray L.

How much is enough depends on the code. The warning shows at >75% regardless of how much memory the code might try to use.

If you've got lots of deep nested function calls, or you're making lots of big locally scoped variables, you might have a problem with memory so close to full. If you're using String class, you'll almost certainly have a problem. Or if you're not doing those things, you could be fine as is - but you're really close to the line, so you should be thinking about sram usage in your code.

...I'm NOT asking for a code fix!

Yet, you also say:

Since upgrading to 1.6.5 I get this error message....

In most cases, seeing the code makes it easier to understand the context of the error message. The other posters have added their ideas on what the answer is. I just think seeing the code often results in a more definitive answer.

I’ve tried to figure this out in a few of different ways.

The first was to insert code that prints or stores the current memory use at various points in the code. There are likely deeply nested places in specific libraries where one may suspect that a maximum is reached.

The second was to add a large global array, increasing its size with each build until the program crashes.

The third was to write a pattern into free memory and then check it later to see where the pattern had been disturbed.

None of these methods are foolproof, not by a long shot, particularly with complex programs that have many possible branches. But they may give you a better idea than the IDE warning does.

The thing to remember is that the warning is new with the new version. If the code has problems due to low memory now then it also would have had the same issues in the old version just no warnings there. If it was working before then it should work now.

How much memory you need free depends on your code. Whatever is the deepest stack of function calls possible with the biggest suite of local variables, then you need enough memory free to hold that. Some code can run with just a few bytes free, some code needs 50% of the dynamic memory free.

Thanks for everyones input, it seems that the answer (in this case anyway) is that I need about 15% of free dynamic memory.

I think the SD.h library has changed since 1.0. I guess my project was ‘on the brink’ before I upgraded, and the changes just used up few bytes more than before. Anyway, I found a couple of unattended Serial.print() statements that weren’t using progmem, and these changes (along with a couple of arrays that I shrunk down) seem to have solved the problems (so far anyway!)

I found that SD (in 1.0) required about 300 bytes of free memory to function. I haven't tested it in 1.6.

SdFat used less stack (something like 70 bytes less) and also a similar amount less static memory. It has also been updated since I tested it.