One of the (optional) arguments to the JVM is the stack size. It's -Xss. I don't know what the default value is, but if the total amount of stuff on the stack exceeds that value, you'll get that error.
Generally, infinite recursion is the cause of this, but if you were seeing that, your stack trace would have more than 5 frames.
Try adding a -Xss argument (or increasing the value of one) to see if this goes away.
What actually causes a java.lang.StackOverflowError is typically unintentional recursion. For me it's often when I intended to call a super method for the overidden method. Such as in this case:
public class Vehicle {
public void accelerate(float acceleration, float maxVelocity) {
// set the acceleration
}
}
public class SpaceShip extends Vehicle {
@Override
public void accelerate(float acceleration, float maxVelocity) {
// update the flux capacitor and call super.accelerate
// oops meant to call super.accelerate(acceleration, maxVelocity);
// but accidentally wrote this instead. A StackOverflow is in our future.
this.accelerate(acceleration, maxVelocity);
}
}
First, it's useful to know what happens behind the scenes when we call a function. The arguments and the address of where the method was called is pushed on the stack (see http://en.wikipedia.org/wiki/Stack_(abstract_data_type)#Runtime_memory_management) so that the called method can access the arguments and so that when the called method is completed, execution can continue after the call. But since we are calling this.accelerate(acceleration, maxVelocity) recursively (recursion is loosely when a method calls itself. For more info see http://en.wikipedia.org/wiki/Recursion_(computer_science)) we are in a situation known as infinite recursion and we keep piling the arguments and return address on the call stack. Since the call stack is finite in size, we eventually run out of space. The running out of space on the call stack is known as overflow. This is because we are trying to use more stack space than we have and the data literally overflows the stack. In the Java programming language, this results in the runtime exception java.lang.StackOverflow and will immediately halt the program.
The above example is somewhat simplified (although it happens to me more than I'd like to admit.) The same thing can happen in a more round about way making it a bit harder to track down. However, in general, the StackOverflow is usually pretty easy to resolve, once it occurs.
In theory, it is also possible to have a stack overflow without recursion, but in practice, it would appear to be a fairly rare event.
Check for any recusive calls for methods. Mainly it is caused when there is recursive call for a method. A simple example is
public static void main(String... args) {
Main main = new Main();
main.testMethod(1);
}
public void testMethod(int i) {
testMethod(i);
System.out.println(i);
}
Here the System.out.println(i); will be repeatedly pushed to stack when the testMethod is called.
I created a program with hibernate, in which I created two POJO classes, both with an object of each other as data members. When in the main method I tried to save them in the database I also got this error.
This happens because both of the classes are referring each other, hence creating a loop which causes this error.
So, check whether any such kind of relationships exist in your program.
When a function call is invoked by a Java application, a stack frame is allocated on the call stack. The stack frame contains the parameters of the invoked method, its local parameters, and the return address of the method.
The return address denotes the execution point from which, the program execution shall continue after the invoked method returns. If there is no space for a new stack frame then, the StackOverflowError is thrown by the Java Virtual Machine (JVM).
The most common case that can possibly exhaust a Java application’s stack is recursion.
The error java.lang.StackOverflowError is thrown to indicate that the application’s stack was exhausted, due to deep recursion i.e your program/script recurses too deeply.
Details
The StackOverflowError extends VirtualMachineError class which indicates that the JVM have been or have run out of resources and cannot operate further. The VirtualMachineError which extends the Error class is used to indicate those serious problems that an application should not catch. A method may not declare such errors in its throw clause because these errors are abnormal conditions that was never expected to occur.
An Example
Minimal, Complete, and Verifiable Example :
package demo;
public class StackOverflowErrorExample {
public static void main(String[] args)
{
StackOverflowErrorExample.recursivePrint(1);
}
public static void recursivePrint(int num) {
System.out.println("Number: " + num);
if(num == 0)
return;
else
recursivePrint(++num);
}
}
Console Output
Number: 1
Number: 2
.
.
.
Number: 8645
Number: 8646
Number: 8647Exception in thread "main" java.lang.StackOverflowError
at java.io.FileOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
at java.io.BufferedOutputStream.flush(Unknown Source)
at java.io.PrintStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.flushBuffer(Unknown Source)
at java.io.OutputStreamWriter.flushBuffer(Unknown Source)
at java.io.PrintStream.newLine(Unknown Source)
at java.io.PrintStream.println(Unknown Source)
at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:11)
at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)
.
.
.
at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)
Explaination
When a function call is invoked by a Java Application, a stack frame is allocated on the call stack. The stack frame contains the parameters of the invoked method, its local parameters, and the return address of the method. The return address denotes the execution point from which, the program execution shall continue after the invoked method returns. If there is no space for a new stack frame then, the StackOverflowError is thrown by the Java Virtual Machine (JVM).
The most common case that can possibly exhaust a Java application’s stack is recursion. In recursion, a method invokes itself during its execution. Recursion one of the most powerful general-purpose programming technique, but must be used with caution, in order for the StackOverflowError to be avoided.
I had this error because I was parsing a list of objects mapped on both sides @OneToMany and @ManyToOne to json using jackson which caused an infinite loop.
If you are in the same situation you can solve this by using @JsonManagedReference and @JsonBackReference annotations.
Annotation used to indicate that annotated property is part of two-way
linkage between fields; and that its role is "parent" (or "forward")
link. Value type (class) of property must have a single compatible
property annotated with JsonBackReference. Linkage is handled such
that the property annotated with this annotation is handled normally
(serialized normally, no special handling for deserialization); it is
the matching back reference that requires special handling
Annotation used to indicate that associated property is part of
two-way linkage between fields; and that its role is "child" (or
"back") link. Value type of the property must be a bean: it can not be
a Collection, Map, Array or enumeration. Linkage is handled such that
the property annotated with this annotation is not serialized; and
during deserialization, its value is set to instance that has the
"managed" (forward) link.