Why are we learning the whole stack/heap things? How does this help us?
Knowing the fundamentals of the java Stack and Heap is vital if anyone want to understand variable scope, object creation issues, memory management, threads and exception handling.
When each time a new object created in Java it goes into the area of memory known as heap. The primitive variables like int, long, float, double…etc are allocated in the stack , if variables are local variables it places in stack and if variables are member variables (i.e. fields of a class) then it place in heap. In Java, methods and its local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed.
At the time of multi-threaded application each thread will have its own stack but will share the same heap. So in this situation care should be taken in your code to avoid any concurrent access issues in the heap space.
The stack is thread-safe & each thread will have its own stack but the heap is not thread-safe unless guarded with synchronization through your code. The stack space can be increased with the –Xss option.
Memory allocation in Recursive Method
All Java methods are automatically re-entrant. It means that several threads can be executing the same method at once, each with its own copy of the local variables. A Java method may call itself without needing any special declarations. This is known as a recursive method call. Given enough stack space, recursive method calls are perfectly valid in Java though it is even tough to debug. Let’s see that with the well known sample program,
public class Factorial {
public long calcFactorial(long number) {
long result=0;
if ( number ==1) {
return 1;
}
System.out.println("Number ::" + number + " :: Result"+ result);
result = calcFactorial (number-1) * number;
System.out.println("Number ::" + number + " :: Result"+ result);
return result;
}
}
To better understand how the calcFactorial () method works; let’s go through a short example. When you compute the factorial of 3, the first call to calcFactorial () will cause a second call to be made with an argument of 2. This invocation will cause calcFactorial () to be called a third time with an argument of 1. This call will return 1, which is then be called a third time with an argument of 1. This call will return1, which is then multiplied by 2 (the value of number in the second invocation). This result (which is 2) is then returned to the original invocation of calcFactorial () and multiply by 3 ( the original value of n). This yields the answer, 6.( To show at what level each call is and what the intermediate answers are, I just used println there in the example. Just do try with different i/p to understand it better).
When a method calls itself, new local variables and parameters are allocated storage on the stack, and the method code is executed with these new variables from the start. A recursive call does not make a new copy of the method. Only the arguments & the local variables are new. As each recursive call returns, the old local variables and parameters are removed from the stack, and execution resumes at the point of the call inside the method. Recursive methods are useful in removing iterations from many sorts of algorithms. All recursive functions are re-entrant but not all re-entrant functions are recursive!!!.
Note: Recursive versions of many routines may execute a bit more slower than the iterative equivalent because of the added overhead of the additional function calls. Many recursive calls to a method could cause a stack overrun. Because storage for parameters and local variables, it is possible that the stack could be exhausted. If this occurs, the java run-time system will cause an exception. However, you probably will not have to worry about this unless a recursive routine runs wild.
Note: Recursive versions of many routines may execute a bit more slower than the iterative equivalent because of the added overhead of the additional function calls. Many recursive calls to a method could cause a stack overrun. Because storage for parameters and local variables, it is possible that the stack could be exhausted. If this occurs, the java run-time system will cause an exception. However, you probably will not have to worry about this unless a recursive routine runs wild.