Search code examples
javascriptstack-overflow

How to find out when the Javascript stack gets full?


I have an algorithm, which works recursively relatively deep, such that a maximum stack size exceeded exception eventually occurs (without being an endless recursion!).

My algorithm can split itself up, to proceed asynchronously using asap, however doing this every time slows down execution massively. I would like to have a (fast) way to find out the current stack usage percentage, so my algorithm can decide to continue synchronously if it is below like 90%, but continue asynchronously when it gets above. I know this value must be around internally, but is there a way to access it?

On the other hand I could imagine to catch the maximum stack size exceeded error, but I read here, that this is not possible (why not? Throwing this exception would mean returning to the caller, which should actually reduce stack size and the older stack entries should still be intact for doing this???)

Of course one way would be to pass a counter variable through all of my functions but this is awkward. Also it is unclear, at which counter value my stack is at 90%, because I do not know, how big the stack is and how big each of my stack frames is.

So actually it seems that JavaScript is born to fail in that case even though the programmer could avoid it, if he had access to the information he needed - which is present somewhere but kept secret for unknown reasons?


Solution

  • There is no way to measure the current stack utilization without tracking it yourself, by passing a variable along or possibly referring to shared state.

    But you can just catch the call stack overflow error when it gets full. (The unclear question you linked was talking about something else, I've written a new answer to clarify.) You could use this to get a rough idea of the available stack size, but that probably isn't guaranteed to be consistent for different functions depending on optimizations and stuff.

    var maxDepth = 0;
    function popTheStack() {
      maxDepth++;
      popTheStack();
    }
    
    try {
      popTheStack();
    } catch (ex) {
      console.log("caught " + ex + " at depth " + maxDepth);
    }