Tuesday, August 20, 2013

Stack and Heap in Java

Here we are going to discuss the concepts of Heap and Stack in Java.

First and foremost thing to remember about the stack and heap is that they are generic terms for ways in which memory is allocated. They can be implemented in different ways.





In Stack, items sit one on top of the other in the order they were placed there, and you can only remove the top one.











In Heap, there is no particular order to the way items are placed. You can reach in and remove items in any order because there is no clear 'top' item.











STACK

First and foremost question come to our mind is what is stack?
A pile of objects, typically one that is neatly arranged: "a stack of boxes" or "a stack of plates"

In term of memory, it's a special region of your computer's memory that store temporay variable, partial results created by functions including your main() function.
The stack is "FILO" (first in last out) data structure, that is managed and optimized by CPU.where new storage is allocated and deallocated at only one end, called the Top of the stack.
Every time a function declares a new variable, it is pushed onto the stack. Then every time a function exits, all of the variable pushed onto the stack by that function, are deleted and memory becomes available for other stack variables.




when program begin executing the main() function, space is allocated on the stack for all the variable declared in stack. If main() function calls a function func1(), additional storage is allocated for the variable declared in func1().
Note: parameter passed by main() function to func1() is stored on stack.

If func1() need to call any additional functions, storage would be allocated at the new Top of stack. when func1() returns, as said above storage for its local variable is deallocated.


Each Java Virtual Machine thread has a private Java Virtual Machine stack, created at the same time as the thread.
The following exceptional conditions are associated with Java Virtual Machine stacks:


  • Stack overflow
    If the computation in a thread requires a larger Java Virtual Machine stack than is permitted, the Java Virtual Machine throws a StackOverflowError.
    The stack has a limited size, and consequently can only hold a limited amount of information. If the program tries to put too much information on the stack, stack overflow will result. Stack overflow happens when all the memory in the stack has been allocated — in that case, further allocations begin overflowing into other sections of memory.
  • Out of Memory
    If Java Virtual Machine stacks can be dynamically expanded, and expansion is attempted but insufficient memory can be made available to effect the expansion, or if insufficient memory can be made available to create the initial Java Virtual Machine stack for a new thread, the Java Virtual Machine throws an OutOfMemoryError.


What can cause StackOverflowError?
Stack overflows are caused (generally I believe) when you make too many nested method calls and are typical in recursive code.

How to fix OutOfMemoryError?
Allow the JVM to use more memory using the -Xmx VM argument.
Improve/Fix the application so that it uses less memory


In addition to this, Stack is also a data structure which is used to store elements in FILO order and it's is available in java.util.Stack<E> providing following function:

  • empty() : Tests if this stack is empty.
  • peek() : Looks at the object at the top of this stack without removing it from the stack.
  • pop() : Removes the object at the top of this stack and returns that object as the value of this function.
  • push(E item) : Pushes an item onto the top of this stack.


The advantage of using the stack to store variable is that you don't need to manage the memory and allocate memory by hand or free it once you don't need it.
Another feature of the stack to keep in mind, is that there is a limit (varies with OS) on the size of variables that can be store on the stack. This is not the case for variables allocated on the heap.

Applications:
Stacks have numerous applications. We see stacks in everyday life, from the books in our library, to the sheaf of papers that we keep in our printer tray. All of them follow the Last In First Out (LIFO) logic, that is when we add a book to a pile of books, we add it to the top of the pile, whereas when we remove a book from the pile, we generally remove it from the top of the pile.

Stack can be used to solve many problem, some of them are that we studied in our curriculum
 * Converting a decimal number into a binary number
 * Towers of Hanoi

 * Expression evaluation and syntax parsing


To summarize the stack:
  • the stack grows and shrinks as functions push and pop local variables
  • there is no need to manage the memory yourself, variables are allocated and freed automatically
  • the stack has size limits
  • stack variables only exist while the function that created them, is running
  • Much faster to allocate in comparison to variables on the heap.
  • Can have a stack overflow when too much of the stack is used.
  • You would use the stack if you know exactly how much data you need to allocate before compile time and it is not too big.


HEAP

The heap (also known as the “free store”) is a large pool of memory used for dynamic allocation.
Java objects reside in an area called the heap. The heap is created when the JVM starts up and may increase or decrease in size while the application runs. When the heap becomes full, garbage collectedDuring the garbage collection objects that are no longer used are cleared, thus making space for new objects.

The heap is a region of your computer's memory that is not managed automatically for you, and is not as tightly managed by the CPU. It is a more free-floating region of memory.

The heap segment provides more stable storage of data for a program; memory allocated in the heap remains in existence for the duration of a program. Therefore, global variables (storage class external), and static variables are allocated on the heap. The memory allocated in the heap area, if initialized to zero at program start, remains zero until the program makes use of it. 

Once you have allocated memory on the heap, you are responsible for using free() to deallocate that memory once you don't need it any more. If you fail to do this, your program will have what is known as a memory leak.
Heap in Java generally located at bottom of address space and move upwards. whenever we create object using new operator or by any another means object is allocated memory from Heap and When object dies or garbage collected ,memory goes back to Heap space in Java.


How to set heap size?
On a 32-bit JVM, the largest heap size you can theoretically set is 4GB. To use a larger heap size, you need to use a 64-bit JVM.

Run this command "java -X" to get the following parameter:
-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set java thread stack size

java -Xms16m -Xmx64m ClassName; this way you can specify the size of the heap memory on program startup.

Heap Division
The heap is divided into generations:
The young generation stores short-lived objects that are created and immediately garbage collected.
Objects that persist longer are moved to the old generation (also called the tenured generation).



The permanent generation (or permgen) is used for class definitions and associated metadata. Permanent generation is not part of the heap. Originally there was no permanent generation, and objects and classes were stored together in the same area. But as class unloading occurs much more rarely than objects are collected, moving class structures to a specific area allows significant performance improvements.


Java Heap Dump and memory leak

Memory leaks are notoriously hard to debug. Java, with its built in garbage collector, handles most memory leak issues. True memory leak happens when objects are stored in memory but are not accessible by running code. These kinds of inaccessible objects are handled by Java garbage collector (in most cases).
Another type of memory leak happens when we have an unneeded reference to the object somewhere. These are not true memory leaks as objects are still accessible, but none the less can cause some nasty bugs.


One way to find memory leaks is analyzing heap dumps.
There are several method to take heap dump, see the following methods

  • HeapDumpOnCtrlBreak
    Set this option when starting JVM.It will create heap dump every time ctrl+break (kill -3) signal is sent to JVM. HeapDumpPath is used to set location of heap dumps.
  • HeapDumpOnOutOfMemoryError
    This JVM option will create heap dump every time when your application throws an OutOfMemoryError
  • Jmap
    Jmap is a tool that comes with JDK installation. To use it we need a PID of our java process.
    For instance, jmap -dump:file=C:\heapdumps\dump.bin 1212
  • HotSpotDiagnosticMXBean
    This option is available in Java 1.6+ and uses sun.management.ManagementFactory.

Once we get the heap dump, we can analyse a tool like VisualVM (also included in JDK installation)to actually try and find the leak.
Another tool is jhat. Command to analyze heap dump

jhat [ options ] <heap-dump-file>

To summarize the heap:

  • Whenever we create objects they are created inside Heap in Java.
  • Java Heap space is divided into three generation : New Generation, Old or tenured Generation or Perm Space.
  • Slower to allocate in comparison to variables on the stack.
  • Used on demand to allocate a block of data for use by the program.
  • Can have fragmentation when there are a lot of allocations and deallocations.
  • Responsible for memory leaks.
  • You can use this java function Runtime.maxMemory(), Runtime.totalMemory(), Runtime.freeMemory() to determine heap size programmtic.
  • Java Garbage collector is responsible for reclaiming memory from dead object and returning to Java Heap space.


When to use Heap and When to use Stack?
If you need to allocate a large block of memory (e.g. a large array, or a big struct), and you need to keep that variable around a long time (like a global), then you should allocate it on the heap. If you are dealing with relatively small variables that only need to persist as long as the function using them is alive, then you should use the stack, it's easier and faster.


I Hope this conclusion will help a bit more !





Fixed size items go on the stack because we know their size. Objects (which vary in size as we update them) go on the heap because we don't know their size
To summarize  if you know the size of the variable (e.g. an int) it goes on the stack. If not, it goes on the heap. And objects always, always, always go on the heap.


QWhich one is stored in stack memory and which is stored in heap?
String one = "java-latte";
String two = new String("java-latte");


You'll have two objects on the heap (two String objects containing "java-latte").
Two references one for each object, on the stack (provided one and two are local variables).

As each thread gets a stack, while there's typically only one heap for the application.
Q. What is their scope?
The stack is attached to a thread, so when the thread exits the stack is reclaimed.
The heap is typically allocated at application startup by the runtime, and is reclaimed when the application.

Q. To what extent are they controlled by the Operating System or language runtime?
The OS allocates the stack for each system-level thread when the thread is created. Typically the OS is called by the language runtime to allocate the heap for the application

Q. What determines the size of each of them?
The size of the stack is set when a thread is created.
The size of the heap is set on application start up, but can grow as space is needed.

Q. What makes one faster?
The stack is faster because all free memory is always contiguous. No list needs to be maintained of all the segments of free memory, just a single pointer to the current top of the stack.




If you know anyone who has started learning java, why not help them out! Just share this post with them. 
Thanks for studying today!...

5 comments:

  1. master piece ,......One who read all these stuffs ,,,I am sure he will crack any java interview

    ReplyDelete
    Replies
    1. I appreciate you like it. That's is the purpose of writing in details.

      Delete
  2. Really good stuff, not available everywhere......Thanks Pardeep

    ReplyDelete
  3. awesome .. wonderful articles .. Thanks Pradeep

    ReplyDelete
  4. Hi Pradeep,
    your article is really very helpful. If u don't mind, i have one doubt. In this article at one place( in Heap Division) u have written "Permanent generation is not part of the heap". But in summary point u have written "Java Heap space is divided into three generation : New Generation, Old or tenured Generation or Perm Space.". Can u clearify this.
    Thanks in advance.

    ReplyDelete