4
votes

I know this question has been answered already via numerous methods:

  • Set maximum stack size (-Xss20m)
  • Avoid the test what so ever - if you need a bigger recursion the problem is within the program.

Those methods are great, but I know there is a problem in my code, and I want to specifically limit (to a small number e.g. 5) the recursion depth, to test whether this is the problem.
Is there a method, like the sys.setrecursionlimit in python?

2
Please add your code to help you checking what's the problem you know it has. :) - Alfabravo
No, there is no setting to limit the recursion depth in Java. If you want to throttle recursions, you need to add a depth parameter to the method and have the method provide it's own depth check. - Andreas
@alfabravo I'm trying to build a concurrent unbalanced binary search tree, I really don't think that this is the question but if you are really interested, I can link you the code - DsCpp

2 Answers

3
votes

The least invasive "Manual" way to do this (also the most hacky) is probably to create a static variable in your class that is having the recursion issue. When you enter the recursive method use it to count the recursion depth (by adding or subtracting) and when you exit, reverse what you did upon entry.

This isn't great but it is a lot better than trying to set a stack depth (Nearly any system call in java will blow through 5 levels of stack without even blinking).

If you don't use a static you may end up having to pass your stack depth variable through quite a few classes, it's very invasive to the rest of your code.

As an alternative I suggest you let it fail "normally" and throw the exception then meditate upon the stack trace for a while--they are really informative and will probably lead you to the source of your problem more quickly than anything else.

static int maxDepth = 5;
public void recursiveMethod() {
    if(maxDepth-- == 0)
        throw new IllegalStateException("Stack Overflow");
    recursiveMethod();
    maxDepth++;
}
1
votes

Create this class:

public class RecursionLimiter {
    public static int maxLevel = 10;

    public static void emerge() {
        if (maxLevel == 0)
            return;
        try {
            throw new IllegalStateException("Too deep, emerging");
        } catch (IllegalStateException e) {
            if (e.getStackTrace().length > maxLevel + 1)
                throw e;
        }
    }
}

Then import static and insert emerge() call into the beginning of any method in your code that can be deeply recursive. You can adjust maximum allowed recursion level via the maxLevel variable. The emerge() procedure will interrupt execution on a level greater than the value of that variable. You can switch off this behaviour by setting maxLevel to 0. This solution is thread-safe because it doesn't use any counter at all.