4

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?

DsCpp
  • 2,259
  • 3
  • 18
  • 46
  • Please add your code to help you checking what's the problem you know it has. :) – Alfabravo Dec 11 '18 at 17:43
  • 2
    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 Dec 11 '18 at 17:45
  • @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 Dec 11 '18 at 17:46

2 Answers2

3

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++;
}
Bill K
  • 62,186
  • 18
  • 105
  • 157
  • As multiple workers use this method, the static way doesn't achieve the goal, but the message is clear, code my way out of it. – DsCpp Dec 11 '18 at 18:04
  • Yes, not very safe for multiple threads although if you synchronized the method or made maxDepth an atomic integer, and then made the max stack depth something like 50 it would probably work as you'd like. (50 is very arbitrary, it would have to be something >= number of threads * expected max depth). – Bill K Dec 11 '18 at 18:48
  • 2
    By the way, if you are simply trying to analyze your code flow to see how deep the stack gets you could use an AtomicInteger (with incrementing/decrementing and logging instead of an exception to see the "Maximum" stack depth you have reached at any given time. – Bill K Dec 11 '18 at 18:57
1

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.

John McClane
  • 3,498
  • 3
  • 12
  • 33