vulture2600:
My theoretical solution would be to erase any non-global memory each time through the loop so any local variables can be initialized any where and never collide with the stack. (I may be getting the stack and heap confused).
Probably not a very good theory. As noted, local variables (“non-global” as you called them) are on the stack (except static ones). So, that space is freed up every time the function exits.
Consensus seems to be that global and static variables are stored in the same memory region as the heap, but not on the heap proper. So, nothing you can do about those.
From the nature of your question, I assume that you’re not doing any dynamic memory allocation yourself. So, if any of the libraries you’re using are abusing the heap, by not freeing allocated dynamic memory when they’re done with it, then there’s nothing you can do in your code. You’d have to go into the library code, find the pointers, determine when that memory is no longer needed, and free / delete to get the space back.
On the other hand, if the libraries need to hold on to that memory to do their job, that just means you’re out of memory. Rewrite your code so it doesn’t need those libraries or move to a processor with more memory.
Edit:
The above ignores the problem of inadequate garbage collection that I’m told processors in the Arduino ecosystem suffer from. All the code could be playing by the proper allocation and freeing rules but the memory space could still be getting fragmented.