I'm using too much RAM. How can this be measured? I would like to know how much RAM I am using in my project, as far as I can tell, there's no way to actually work that out (other than going through and calculating it myself). I have got to a stage in a rather large project where I have determined that I am running out of RAM. 

I have determined this because I can add a section and then all hell breaks loose somewhere else in my code for no apparent reason. If I #ifndef something else out, it works again. There is nothing programatically wrong with the new code. 

I suspected for a while that I was getting to the end of available RAM. I don't think I'm using too much stack (although it's possible), what is the best way to determine how much RAM I am actually using?

Going through and trying to work it out, I have problems when I get to enums and structs; how much memory do they cost? 

first edit: ALSO, I have edited my sketch so much since starting, these are not the actual results I initially got, but they are what I am getting now. 

  text     data     bss     dec     hex filename
 17554      844     449   18847    499f HA15_20140317w.cpp.elf
 16316      694     409   17419    440b HA15_20140317w.cpp.elf
 17346      790     426   18562    4882 HA15_20140317w.cpp.elf


The first line (with text 17554) was not working, after much editing, the second line (with text 16316) is working as it should. 

edit: the third line has everything working, serial reading, my new functions, etc. I essentially removed some global variables and duplicate code. I mention this because (as suspected) it's not about this code per sae, it has to be about the RAM usage. Which brings me back to the original question, "how to best measure it" I'm still checking out some answers, thanks.

How do I actually interpret the above information? 

So far my understanding is: 

`TEXT` is program instruction memory
`DATA` is variables (unitialised?) in program memory
`BSS`  is variables occupying RAM


since BSS is considerably less than 1024 bytes, why does the second work, but the first doesn't? If it's DATA+BSS then both occupy more than 1024. 

re-edit: I edited the question to include the code, but now I've removed it because it really had nothing to do with the problem (other than maybe poor coding practices, variable declarations and the like). You can review the code by looking back through the edits if you really want to see it. I wanted to get back to the question at hand, which was more based around: How to measure RAM usage.
You can use the functions provided AVRGCC: Monitoring Stack Usage

The function was intended to check the stack usage but what it reports is the actual RAM that has never been used (during execution). It does so by "painting" (filling) the RAM with a known value (0xC5), and then checking the RAM area counting how many bytes have still the same initial value.
The report will show the RAM that has not been used (minimum free RAM) and therefor you can calculate the max RAM that has been used (Total RAM - reported RAM).

There are two functions:


StackPaint is executed automatically during initialization and "paints" the RAM with the value 0xC5 (can be changed if needed).
StackCount can be called at any point to count the RAM that hasn't been used.


Here is an example of usage. Doesn't do much but is intended to show how to use the functions.



// -----------------------------------------------------------------------------
extern uint8_t _end;
extern uint8_t __stack;

void StackPaint(void) __attribute__ ((naked)) __attribute__ ((section (".init1")));

void StackPaint(void)
{
#if 0
    uint8_t *p = &amp;_end;

    while(p &lt;= &amp;__stack)
    {
        *p = 0xc5;
        p++;
    }
#else
    __asm volatile ("    ldi r30,lo8(_end)\n"
                    "    ldi r31,hi8(_end)\n"
                    "    ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
                    "    ldi r25,hi8(__stack)\n"
                    "    rjmp .cmp\n"
                    ".loop:\n"
                    "    st Z+,r24\n"
                    ".cmp:\n"
                    "    cpi r30,lo8(__stack)\n"
                    "    cpc r31,r25\n"
                    "    brlo .loop\n"
                    "    breq .loop"::);
#endif
} 


uint16_t StackCount(void)
{
    const uint8_t *p = &amp;_end;
    uint16_t       c = 0;

    while(*p == 0xc5 &amp;&amp; p &lt;= &amp;__stack)
    {
        p++;
        c++;
    }

    return c;
} 

// -----------------------------------------------------------------------------

void setup() {

Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
Serial.println(StackCount(), DEC);  // calls StackCount() to report the unused RAM
delay(1000);
}