Java applications need a certain amount of RAM on a computer to run. Each time an object or variable is declared, it needs more RAM. Simply designating enough memory to hold every value declared and run each method would lead to a bloated application. To keep application memory requirements, lean, it is partitioned in ways that require less memory and allows the application to run more quickly. The Java Virtual Machine (JVM) divides memory between Java Heap Space and Java Stack Memory in a way that only uses memory that’s needed.
Java Heap Memory
It is created by the Java Virtual Machine when it starts. The memory is used if the application is running. Java runtime uses it to allocate memory to objects and Java Runtime Environment (JRE) classes. When an object is created, it is always created in Heap and has global access. That means all objects can be referenced from anywhere in the application. The memory is allocated during the execution of instructions written by programmers. Note that the name heap has nothing to do with the heap data structure.
It is called a heap because it is a pile of memory space available to programmers to allocate and de-allocate. Every time we made an object it always creates in Heap-space and the referencing information to these objects is always stored in Stack-memory. Heap memory allocation isn’t as safe as Stack memory allocation because the data stored in this space is accessible or visible to all threads. If a programmer does not handle this memory well, a memory leak can happen in the program.
The Heap-memory allocation is further divided into the following categories:
It works to free memory by clearing any objects without any references in the methods. These are objects that are no longer being used. Clearing them ensures they don’t take up space in the Heap.
It’s the portion of the memory where all the new data(objects) are made to allocate the space and whenever this memory is filled then the rest of the data is stored in Garbage collection. The nursery is the younger generation where the new objects are stored. When the nursery is full, garbage collection cleans it out. Note only the memory space for the nursery is full. There is still memory in the old generation.
Old or Tenured Generation
This is the part of Heap-memory that contains the older data objects that are not in frequent use or not in use at all are placed.
This is the portion of Heap-memory that contains the JVM’s metadata for the runtime classes and application methods.
We receive the corresponding error message if Heap-space is entirely full, Out of Memory Error by JVM.
This memory allocation scheme is different from the Stack-space allocation, here no automatic de-allocation feature is provided. We need to use a Garbage collector to remove the old unused objects to use the memory efficiently.
The processing time (Accessing time) of this memory is quite slow as compared to Stack-memory. Heap memory is also not as threaded-safe as Stack-memory because data stored in Heap-memory are visible to all threads.
The size of the Heap-memory is quite larger compared to the Stack-memory. Heap memory is accessible or exists if the whole application (or java program) runs.
Java Heap Space is used throughout the application.
The Heap Space contains all objects created.
Memory allocation in the Heap Space is accessed through a complex, young-generation, old-generation system.
Java Stack Memory
This is the temporary memory where variable values are stored when their methods are invoked. After the method is finished, the memory containing those values is cleared to make room for new methods. When a new method is invoked, a new block of memory will be created in the Stack. This new block will store the temporary values invoked by the method and references to objects stored in the Heap that is being used by the method. Any values in this block are only accessible by the current method and will not exist once it ends. When the method ends, that block will be erased. The next method invoked will use that empty block. This “last in, first out” method makes it easy to find the values needed and allows fast access to those values. The allocation happens on contiguous blocks of memory. We call it a stack memory allocation because the allocation happens in the function call stack. The size of memory to be allocated is known to the compiler and whenever a function is called, its variables get memory allocated on the stack. And whenever the function call is over, the memory for the variables is de-allocated. This all happens using some predefined routines in the compiler. A programmer does not have to worry about memory allocation and de-allocation of stack variables. This kind of memory allocation is also known as Temporary memory allocation because as soon as the method finishes its execution all the data belonging to that method flushes out from the stack automatically. This means any value stored in the stack memory scheme is accessible if the method hasn’t completed its execution and is currently running.
It’s a temporary memory allocation scheme where the data members are accessible only if the method () that contained them is currently running.
It allocates or de-allocates the memory automatically as soon as the corresponding method completes its execution.
We receive the corresponding error Java. lang. Stack Overflow Error by JVM, If the stack memory is filled.
Stack memory allocation is considered safer than heap memory allocation because the stored data can only be accessed by the owner thread.
Memory allocation and de-allocation are faster as compared to Heap-memory allocation. Stack memory has less storage space as compared to Heap-memory.
Difference between Java Heap Space and Stack Memory
Based on the above explanations, we can easily conclude the following differences between Heap and Stack memory.
Heap memory is used by all the parts of the application whereas stack memory is used only by one thread of execution.
Whenever an object is created, it’s always stored in the Heap space and stack memory contains the reference to it. Stack memory only contains local primitive variables and reference variables to objects in heap space.
Objects stored in the heap are globally accessible whereas stack memory can’t be accessed by other threads.
Memory management in the stack is done in a LIFO manner whereas it’s more complex in Heap memory because it’s used globally. Heap memory is divided into Young-Generation and Old-Generation.
Stack memory is short-lived whereas heap memory lives from the start till the end of application execution.
We can use the -XMS and -XMX JVM options to define the start-up size and maximum size of heap memory. We can use -XSS to define the stack memory size.
When stack memory is full, Java runtime throws java. lang. Stack Overflow Error whereas if heap memory is full, it throws java. lang. Out of Memory Error.
Stack memory size is very less when compared to Heap memory. Because of simplicity in memory allocation (LIFO), stack memory is very fast when compared to heap memory.
In a stack, the allocation and de-allocation are automatically done by the compiler whereas, in heap, it needs to be done by the programmer manually.
Handling of the Heap frame is costlier than handling the stack frame. Memory shortage problem is more likely to happen in stack whereas the main issue in heap memory is fragmentation.
Stack frame access is easier than the heap frame as the stack has a small has on of memory and is cache-friendly but in the case of the heap, the frames are dispersed throughout the memory, so it causes more cache misses.
A stack is not flexible, the memory size allotted cannot be changed whereas a heap is flexible, and the allotted memory can be altered. Accessing the time of the heap takes more than a stack.
Benefits of using stack:
Helps you to manage the data in a Last in First Out (LIFO) method which is not possible with a Linked list and array.
When a function is called the local variables are stored in a stack, and it is automatically destroyed once returned.
A stack is used when a variable is not used outside that function.
It allows you to control how memory is allocated and deallocated.
Stack automatically cleans up the object.
Not easily corrupted
Variables cannot be resized.
Benefits of using heap memory:
Heap helps you to find the greatest and minimum number.
Garbage collection runs on the heap memory to free the memory used by the object.
Heap method is also used in the Priority Queue.
It allows you to access variables globally.
Heap doesn’t have any limit on memory size.
Disadvantages of using Heap
It can provide the maximum memory an OS can provide
It takes more time to compute.
Memory management is more complicated in heap memory as it is used globally.
It takes too much time in the executant compared to the stack.
Disadvantages of using Stack
Stack memory is very limited.
Creating too many objects on the stack can increase the risk of stack overflow.
Random access is not possible.
Variable storage will be overwritten, which sometimes leads to undefined behaviour of the function or program.
The stack will fall outside of the memory area, which might lead to an abnormal termination.
When to use the Heap or stack?
You should use a heap when you require to allocate a large block of memory. For example, if you want to create a large size array or big structure to keep that variable around f a long time then you should allocate it on the heap.
However, if you are working with relatively small variables that are only required until the function using them is alive. Then you need to use the stack, which is faster and easier.
Comparison of Stack and Heap Memory
Memory is allocated in a contiguous block.
Memory is allocated in any random order.
Allocation and De-allocation
Automatic by compiler instructions.
Manual by the programmer.
Shortage of memory
Locality of reference
Thread safe, data stored can only be accessed by the owner
Not Thread safe, data stored visible to all threads
Resizing is possible.
Data type structure
Static memory allocation is preferred in the array.
Heap memory allocation is preferred in the linked list.