Dont Smack The Stack (Deal With Stack Overflow Exceptions)

At times, Java programmers come across this scenario when they have to handle 'Stack Overflow' exception in Java. This probably and mostly happens due to some petty mistakes in the code. Stack overflow happens when all the memory that is allocated to the stack is totally used. Most of the programming languages have limited memory for the stack. So, when stack memory is totally used, it results in program crash.

Stack overflow usually happens when a recursive function is used infinitely (which is probably due to some naive coding mistake). Alternatively, it can also happen when a very large stack variable is used.

Some programming languages (specially functional programming languages like 'Scheme') use 'Tail Recursion' to avoid 'Stack Overflow' errors and to improve efficiency. In this kind of technique, the last statement/operation in a method/function is a recursive call. By this use of logic, recursions can easily be transformed to iterations and thus help in effective use of memory/data-structures.

Below are some scenario's in which this kind of java exception happens:

1) Infinite Recursion:

If you have designed java applications with interfaces or abstract classes, sometimes you might bump into situations, where in, you have overridden a method from some interface/class that you are implementing and you mistakenly called the method of the interface/class, instead of calling some other method or implementing a totally new functionality. This code would not throw any compile time errors. But, at runtime, you would be surprised to see 'Stack Overflow' exceptions. Below is one trivial example:

public interface Interface1 {
public void doSomeShit();
}


Here's a class that implements 'Interface1', overrides the method and calls the same method. This is pretty stupid coding, but there might be scenario's where you might not notice because of code complexity or due to neglect.

public class Interface1Impl implements Interface1
{
public static void main(String[] args) {
Interface1Impl i = new Interface1Impl();
i.doSomeShit();

}

public void doSomeShit() {
doSomeShit();
}
}


The above program compiles fine, but throws 'Stack Overflow' exception, at runtime.

Example 2:

public class StackOverflowDemo1
{
public static void main(String[] args) 
{
StackOverflowDemo1 sofd = new StackOverflowDemo1();
sofd.method1();
}

public void method1() {
method2();
}

public void method2() {
method1();
}
}



Example 3:

public class StackOverflowDemo2
{
public static void main(String[] args) 
{
StackOverflowDemo2 sofd = new StackOverflowDemo2();
sofd.valueOf(sofd);
}

public String valueOf(Object obj) {
return valueOf(obj);    
}
}



The above code throws 'Stack Overflow' exception, as you are doing nothing special, but overriding the 'String' objects 'valueOf' method and calling it again.

The JVM (Java Virtual Machine) uses stack to store the state of java method invocations (excluding Native methods). The state of a method is in its local variables, parameters, return value and whatever business/plain logic involved in that method. Java's programming model further splits 'Java Stack' into 'Stack frames' (which is probably a programming concept for efficiently handling the state of a method, et al things). Each and every method's state is associated with a particular stack frame. When the method completes, the stack frame is deallocated. This is how the methods parameters, local variables, return type variables are always thread safe.

If you have problems with Java stack or if you want to increase the size of Java Stack, you can use the following command:

Java - Xss Stack-Size

Replace the 'Stack-Size', with the size of memory that you need.

Thats it! Happy coding and 'Protect The Stack'! ;-) (Now, the heap's calling..huh)

1 comment:

Note: Only a member of this blog may post a comment.