Search code examples
recursionstack-overflow

What affects stack size in recursion?


Exactly what parts of a recursive method call contributes to the stack--say, the returned object, arguments, local variables, etc.?

I'm trying to optimize the levels of recursion that an Android application can do on limited memory before running into a StackOverflowException.

Thanks in advance.


Solution

  • If you run out of stack space, don't optimize your stack usage. Doing that just means the same problem will come back later, with a slightly larger input set or called from somewhere else. And at some point you have reached the theoretical or practical minimum of space you can consume for the problem you're solving. Instead, convert the offending code to use a collection other than the machine stack (e.g. a heap-allocated stack or queue). Doing so sometimes results in very ugly code, but at least it won't crash.

    But to answer the question: Generally all the things you name can take stack space, and temporary values take space too (so nesting expressions like crazy just to save local variables won't help). Some of these will be stored in registers, depending on the calling convention, but may have to be spilled(*) anyway. But regardless of the calling convention, this only saves you a few bytes, and everything will have to be spilled for calls as the callee is given usually free reign over registers during the call. So at the time your stack overflows, the stack is indeed crowded with parameters, local variables, and temporaries of earlier calls. Some may be optimized away altogether or share a stack slot if they aren't needed at the same time. Ultimately this is up to the JIT compiler.

    (*) Spilling: Moving a value from a register to memory (i.e., the stack) because the register is needed for something else.