Stack vs Heap in Java
In Java, whenever we declare an object or create a variable, whether it is an instance variable, local variable, or static variable, a certain memory is used to store the data. The amount of data or size is determined by the type of data type declared. In Java, there are two types of data, primitive and non-primitive.
Primitive data types:
Type | Size (in bits) |
byte | 8 |
short | 16 |
int | 32 |
long | 64 |
float | 32 |
double | 64 |
char | 16 |
boolean | 1 |
Non-primitive data type:
- Class
- Object
- String
- Array
- Interface
There are significant distinctions between primitive and non-primitive data types, which are as follows.
- The primitive data types are initialized and declared while keeping the first letter in the small case. In contrast, the non-primitive datatypes are initialized and declared while keeping the first letter in a large case. Because non-primitive data types are treated as objects in Java. For example:
String st = "Sahil"; // non- primitive data type
int a = 100; //primitive data type
- Variables in primitive data types can only store one value at a time, whereas non-primitive data types allow us to store numerous values of the same or distinct types.
- For primitive type variables, the stack retains all of the data, whereas, for reference types, the stack holds a pointer to the object on the heap.
Java's memory management plays an important role in its functionality. Java Virtual Machine properly uses both the memory to execute the program. And thus, to do so, the memory in Java is divided into the following types: stack memory and heap memory.
Stack Memory
Stack memory is also known as Java's temporary memory, storing variables and order of method execution. It uses a linear data structure. The stack implements the concept of LIFO order. To understand how the stack works, imagine a pile of books. The only way to take out a book lying in the middle of the pile of books is by taking out books above it one by one.
Similarly, stack stores data in a pile or a stack. To access the data at the bottom, you need to remove all the above data. It implements the following interfaces.
- List
- Iterable
- Collection
- Cloneable
- RandomAccess
- Serializable
It performs the following operations:
empty ()
This is a return type method; return true if the stack is empty.
peek ()
This is a return type function that returns the stack's top element. When the stack is empty, this function throws an EmptyStackException.
pop ()
This return type function returns the top element from the stack. This method invokes EmptyStackException when the stack is empty.
push ()
Adds a new element to the stack's top.
Heap Memory
It is used when we need is to store object classes and dynamically allocate memory. The memory is created when the Java Virtual Machine initiates its function, and the allocation of size may increase or decrease. Whenever a new object is created or declared, space is given to it in heap memory, while the reference variable of the same object is stored inside the Stack Memory. Unlike the stack, the heap memory does not store the data in any order, i.e., it does not store memory continuously. It has a feature called Garbage Collector. It deletes all the objects which are no longer being used. When the heap memory has no space to store a new object, it invokes Java.lang.OutOfMemoryError.
String arr = new String ();
arr = "Sahil Deshmukh";
The reference variable arr is stored in stack memory in the above code, and its value Sahil Deshmukh is stored in heap memory. The heap memory is further segregated into the following parts: -
- Permanent generation
- Code Cache
- Young generation
- Old generation
- Survivor Space
Difference Between Stack and Heap
Stack Memory | Heap Memory |
It acts as Random-access memory for Java and stores variables, methods, and reference variables. | It stores objects. |
It implements the LIFO order. | It does not implement any order and dynamically allocates memory. |
Users are not permitted to alter changes or manipulate the memory. | Users are allowed to alter the memory. |
It is comparatively faster in allocating memory. | It is comparatively faster in allocating memory. |
It is comparatively smaller in size. | It is comparatively larger. |
It continuously allocates memory. | It randomly allocates memory. |
It is thread-safe since each thread has its stack. | Correct code synchronization is essential as it is not a thread-safe. |
When the stack’s size reaches its limits, It throws Java.lang.StackOverFlowError. | When the heap memory has no space to store a new object, it invokes Java.lang.OutOfMemoryError. |
The stack memory exists only as long as the current method is active. | Once the current application is closed, the heap space also gets closed. |