A while ago I wrote an article on “how to crash a JVM”, the purpose of that article is to identify the end limits of JVM, instead it stirred quite some controversy in other areas. If you are interested to know more on that article, you can read it here. This is a follow-up article to that one where I would like to touch on StackOverflow and why & when it occurs.
As you might know already, the following code snippet throws StackOverflowError.
public class StackOverflowTest {
public static void main(String[] args) {
main(args);
}
}
If you read the javadoc of StackOverflowError, it says that error happens when application “recurses too deeply”. There are two key words to underline here… “recurse” and “deep”. The word recursion according to google (Did you mean: recursion
) & programmers lingo, some method calling itself. So, it’s very natural to think StackOverflowError happens only when we run into this inifinite recursion scenario. But, thats not entirely true. It could also happen when we have method call chain which is “too deep”.
So, in order to find out how deep is “too deep”, I wrote this code snippet. Obviously, it will vary between different JRE versions, OS etc and you can also increase the stack size limit by setting -XX VM param.
In order to prove the stack overflow in “non-recursion” scenario, here is a Java code that will create, compile & run Java code with nested method call chain of limit set to 7000.
So, if you think this little more deeper, someone like me would wonder.. Is it a limitation that a Java class/application cannot have more than certain number of methods? If yes, how does all the enterprise class software products written in millions of lines of Java code working? The answer to that question is… Yes, it is a limitation, but in only one thread. So, almost any enterprise/mid range Java project/product cannot be written in such a way that it would run in only one main thread and if it written that way, this is the limit you hit.
So, if we come back to our original problem and see if we can make it run. Here is how…
public class StackOverflowLimitWithThreadTest {
private static int recursionLimit = 0;
public static void main(final String[] args) {
new Thread(new Runnable(){
public void run() {
System.out.println("recursionLimit++ = " + recursionLimit++);
main(args);
}
}).start();
}
}