Sometime back I wrote a couple of posts about Java Garbage Collection and Java is Pass by Value. After that I got a lot of emails to explain about Java Heap Space, Java Stack Memory, Memory Allocation in Java and what are the differences between them. You will see a lot of reference to Heap and Stack memory in Java, Java EE books and tutorials but hardly complete explanation of what is heap and stack memory in terms of a program.
Java Heap space is used by java runtime to allocate memory to Objects and JRE classes. Whenever we create an object, it’s always created in the Heap space. Garbage Collection runs on the heap memory to free the memory used by objects that don’t have any reference. Any object created in the heap space has global access and can be referenced from anywhere of the application.
Java Stack memory is used for the execution of a thread. They contain method-specific values that are short-lived and references to other objects in the heap that is getting referred from the method. Stack memory is always referenced in LIFO (Last-In-First-Out) order. Whenever a method is invoked, a new block is created in the stack memory for the method to hold local primitive values and reference to other objects in the method. As soon as the method ends, the block becomes unused and becomes available for the next method. Stack memory size is very less compared to Heap memory.
Let’s understand the Heap and Stack memory usage with a simple program.
package com.journaldev.test;
public class Memory {
public static void main(String[] args) { // Line 1
int i=1; // Line 2
Object obj = new Object(); // Line 3
Memory mem = new Memory(); // Line 4
mem.foo(obj); // Line 5
} // Line 9
private void foo(Object param) { // Line 6
String str = param.toString(); //// Line 7
System.out.println(str);
} // Line 8
}
The below image shows the Stack and Heap memory with reference to the above program and how they are being used to store primitive, Objects and reference variables. Let’s go through the steps of the execution of the program.
Based on the above explanations, we can easily conclude the following differences between Heap and Stack memory.
java.lang.StackOverFlowError
whereas if heap memory is full, it throws java.lang.OutOfMemoryError: Java Heap Space
error.That’s all for Java Heap Space vs Stack Memory in terms of java application, I hope it will clear your doubts regarding memory allocation when any java program is executed.
Reference: https://en.wikipedia.org/wiki/Java_memory_model.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
what about static methods and static variables? are they stored in stack or heap memory?
- pk
class structure and static variables are stored in a separate memory pool area known as Method Area.
- Sankar
Static Variables are stored in HEAP. Classes and all of the data applying to classes (not instance data) is stored in the Permanent Generation section of the heap. https://net-informations.com/java/cjava/memory.htm John
- johnsonjeven
This is very useful. Thanks for your great work. public static void main(String[] args) - what about args? It is stored in stack right?
- kanaga
Awesome ! best place to brush up concepts !
- Sorrowfull Blinger
On the public static void main(String[] args) - Does the memory for args[] allocated in heap space but the reference is allocated in Stack - Is my understanding correct?
- Shaik
Yes, it’s String array… hence Object, so stored in Heap memory. However main method contains the references in stack memory.
- Pankaj
Thanks for your articles. They are very usefull!
- Dmitry
Thanks a lot Pankaj. This article is very great! Can You write a article about Thread-Safe? Because I don’t know Why a global variable is not-thread-safe. I reseach very much about it. I use “new” operation but a global variable in that class, it’s not Thread-Safe. Thanks in advance!
- i_know_nothing
This is a very nice explanation of Stack and Heap Memory and their differences. I wish you could write a bit about instance variables and static variables. Well Done !
- Abhishek Thakur
Nice artical , greate and simple explanation .
- Vishnu
Thank you for sharing this article. One point i have to raise here. regarding “int i = 1”. Not sure if this is because of “escape analysis” or something else like “interning”. But what i tested it goes to “Heap”. Following is my test:
package immutable; public class Immutable_One { private int i = 2; public int get() { return i; } }
package immutable; public class Immutable_Two { private int j = 2; public int get() { return j; } }
package immutable; public class ImmutableTest { public static void main(String[] args) { Immutable_One immutable_One = new Immutable_One(); int i = immutable_One.get(); Immutable_Two immutable_Two = new Immutable_Two(); int j = immutable_Two.get(); if (i == j) { System.out.println("Equal"); } else { System.out.println("NOT Equal"); } } }
The result comes “Equal”.- Arfeen
Its basically because of the caching. If we open the Integer class, you can see that value between -128 to 127 are cached. In the above program if you put any value outside of the range, you will the desired behavior. So as per my thought- What Pankaj mentioned in picture “int i = 1” as part of stack, that must be re-corrected and move it to heap area which can be shared among all thread.
- Tanzy
I don’t see how this is a valid test. You’re comparing the value of two primitives, which is a straight up comparison of their values. No references involved at that point. For a better test, make i and j Integer objects, and return Integer objects. Than you’ll see the caching behavior that Tanzy mentions.
- cc10123
Agree. He is just comparing primitive values, 2 == 2 returns true. He should try something like this: Integer a = Integer.valueOf(2); Integer b = Integer.valueOf(2); System.out.println(a.equals(b)); // comparing values System.out.println(a==b); // comparing references Integer c = new Integer(2); Integer d = new Integer(2); System.out.println(c.equals(d)); // comparing values System.out.println(c==d); // comparing references
- Michael
If it were truly “pass by value” as in the case with c++ then it would be a copy/clone of the object. Calling the foo() method would not affect the blue balloon color value in the main method. But in the example it does because it is “referencing” the memory space in the heap and changing the value. Much like you would when “passing by reference”. However, I also see the point of how the value is used (as if a copy/clone were passed in) in the swap method. The manipulation of the balloon colors in the swap method does not affect the balloons variables in the main method. Its almost like its “pass by reference or value”. In either case the presentation was awesome as well as the write up. Thanks for your efforts.
- Alalonks
Crisp, Clear and to the point…great article. keep rocking!!!
- Sudhakar
I have a doubt in static reference and static primitive. public static A a = new A(); public static int b = 5; where ‘a’ reference and ‘b’ primitive live (stack or heap). When it will eligible for garbage collection.
- Vel
Nice Article.
- Prabhath
Very well explained, thanks!
- Pieter
Nice video, thanks !
- Upir
Java is not only “Pass by Value”, it’s also “Pass by Reference” which depends if primitives are passed or reference objects (the name implies it). If Java would be purely “Pass by Value“, the following program public class Test { public static void main(String[] args) { Integer i = 2; System.out.println("i initialized = " + i); List u = new ArrayList(Arrays.asList(“1”, “2”, “3”)); System.out.println("u before method = " + u); test(i); test1(u); System.out.println("i outside method = " + i); System.out.println("u AFTER method call = " + u); } private static void test1(List u) { u.add(“blah”); System.out.println("u inside method = " + u); } private static void test(int i) { i = i + 1; System.out.println("i inside method = " + i); } } …would not print u inside method = [1, 2, 3, blah] […] u AFTER method call = [1, 2, 3, blah]
- Alexander Orlov
In the test(int i) method, when i is being printed its the local variable value which is a copy of i in main(), coming back in main() when i is printed the value still remains same hence its PassByValue.
- Purnendu Dutta
In both cases it’s pass by value. In case of ‘i’, value of ‘i’ is copied in the method ‘test()’. In case of ‘u’, value of ‘u’ which is a reference, is copied in method ‘test1()’. Check this code: public static void main(String[] args) { List list = Arrays.asList(“One”, “Three”, “Five”); passByReferenceTest(list); System.out.println(list); // n1: What is printed here? } private static void passByReferenceTest(List list) { list = Arrays.asList(“Two”, “Four”, “Six”); // n2 } If pass by reference was possible then the assignment at line n2 would have changed the list reference in main() and therefore “Two”, “Four”, “Six” would have been printed at line n1. Pointers in C behave like that.
- Miroslav Manchev
Nice Article, I have one question. Do we have separate stack memory for each Thread we create?
- Suraj Shrestha
Thanks man, you made my day :D
- Huy
Thanks dude. Thanks for explaining it neat and clear… (y) cheers!
- Arjun
Very well! I learn o lot form this passage!
- YangFang
Very nice and useful Information… Thanks a lot :)
- Subrahmanyam
easily i got understand by reading this… thanks to clear my doubt
- shneha
not all objects allocated in Heap ! but static ones , you created Memory and Object instances in a static context so the variables in that context created in heap ! if you create them in foo method stack memory will be used , please correct this big wrong article!!!
- z6qc@yahoo.com
i have no idea what you are talking here.
- Pankaj
We mean that in foo(Object param) here param is a local variable of type Object in foo() so it won’t get space in heap but according to ESCAPE ANALYSIS(by java 6e14) that param will be treated similar to those local variables of primitive types in foo() and gets space in stack and not in heap.!! Will you please clear this out Sir. Thank You.
- PriyaYT
You are right…but escape analysis is not always possible, In this trivial case it was easy for the compiler to find out.
- Anirban Pal
Nice Article my doubt is class Memory{ Memory memory=new Memory(); } where memory is get stored…on heap??
- Amit
stack
- satyam
Heap. The Memory object would always be created on the heap, regardless of where its reference lives. In your example, the memory (small ‘m’) reference is also on the heap, because it exists as part of the Memory class which is on the heap.
- cc10123
You mentioned stand alone program. So My question is once application finish executing, what will happen to String pool, it will be memory or it will remove from heap?
- Shambhu
Once application is finished executing, JVM terminates and all the memory is released to OS.
- Pankaj
simplicity makes this article awesome
- satyam
thnks a lot
- selvi
Awesome explanation, thank you so much.
- Krishna
Very well explained
- Akanksha
What is the stack memory allocated to each java program?. What is the size of stack memory?
- Rangrao Patil
very good explanation. keep it up!
- varun
Hi, I have one question. i faced this question in one of the interview, String s1=new String(“abc”); String s2=new String(“abc”); int a=10; int b=10; if a==b is true then why s1==s2 is false
- arun
1. int is not an object, java handles primitive data types differently, reducing memory footprint by caching the variables, something like String Pool. 2. String is an object, when new operator is used then a new variable is created rather than checking in String Pool to find some already existing one. Based on above points, I think you can clearly see the reason behind the program output.
- Pankaj
StringBuilder sb1 = new StringBuilder(“Niraj”); StringBuilder sb2 = new StringBuilder(“Niraj”); System.out.println("sb1.equals(sb2) "+(sb1.equals(sb2))); Then why this is give “false”
- Niraj
That gives ‘false’ because you are comparing two unique StringBuilder objects, not the actual String values. If you changed your code to this: sb1.toString().equals(sb2.toString()) That should give you ‘true’. Remember, when you have an object (like String) it has an object reference (or ID) as well as an actual “value”. If you compare the object references, you will find they are different, even if the object values are the same.
- Alex
Great work…written in simple way to understand it :) You can add some advanced level theory also later to make this article perfect like…static/non static context etc
- Swapnil Suhane
Thanks a lot, very well framed. Easy & Simple to understand
- Jinesh
Very good explanation . Keep doing a great job !
- Lucian
Hello Pankaj, Above explanation of memory allocation is very nice and useful. But I am still confused for following scenario : Class A { public A(){…} public void test(){…} public void test1(){…} } class B extends A { public B(){…} public void test(){…} public void test2(){…} } now in main method I am creating object in this way : A a = new B(); a.test(); a.test1(); a.test2(); so how memory allocation will work ? Thanks in Advance.
- Sushant
that is not going to compile cause class A doesn’t have test2() method.
- mista
How much memory is allocated in heap for String ? for example if i define String name; in class
- Pratap
Well done! This really helped me.
- CS Student
Excellent Boss !!! clear explanation
- Ram
Loved the way you have written this article. Excellent. Understood the concept. Thanks, Cheers
- Sid
This is good explanation. Can you give explanation on this involving array manipulation?
- Farhan
Good work!? Thank you…☺
- Sarvesh Singh
Java is both *Pass by value* and *Pass by reference* why baloon.setColor(“Red”); changed the value of color to “Red” when printed in main() method?
- Selvakumar Esra
where an object and its reference will create for all type of inner classes ?
- Sumant Dharkar
Where would the references to an Object which is an instance variable be stored. For eg. Class Memory{ Memory mem = new Memory(); public Memory(){ } } So, where would be the “mem” reference be stored as it is not tied to any code/method.
- Melwin
It would be stored in the heap along with all the other contents (instance primitive variables) in the heap.
- Satishchandra Singh
I want to ask how we can elaborate using stack memory and heap memory that two methods are accessing to the same object means (This Reference and Other References to the same object at method level). The purpose is that we want to see the dependencies between two methods using same data.
- Mrs Afzal
Hi , What is about String args[] variable. Will this reference variable will not be listed in stack of main method.
- Dheeraj
I watched the video. It’s excellent. But I have a question about who collects Stack Memory? Refrences will always be in the Stack and as soon as the refrence goes out of scope object is available for the Garbage collection but what happens to the refrence memory in the stack?
- Jim Mehta
Stack frame memory gets deallocated automatically when method exists, because it’s get popped from the stack.
- andrey
Thank for your great work! This is interesting!
- rungrengreng
Nice article. a small suggestion in diagram… can you write steps 1,2,3… so that when step 7 occurs where is the flow can be easily referred for beginners
- Reddeppa Kande
Good work boss…
- Nagaraju
Hi Thanks for this awesome brief about heap and stack memory. [Based on the above explanations, we can easily conclude 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.] Question: Block for main thread always exists. So as per me stack memory is used only by one thread of execution is not totally correct. Please explain me if I am wrong.
- Prabhat Kumar
String s1=new String(“hello”); As I know two objects will be created…but interviewer asked to prove…Pls help me out @pankaj…
- LittleLion
java creates an object xyz in memory and then a x object which has the ingredients of object xyz. Then xyz is destryed (lost). So at the end we created 2 object but now we have one !
- Rakesh
The way explained is easily grasp difference between Heap Space vs Stack – Memory. thanks for publishing this article.
- Gafoor
Great explanation!
- Jun Hua
Superb Explain Pankaj… After a long time now i got the proper answer HERE… Hats Off to you
- Saurabh
Wonderful explanation
- Sailaja Gudala
Thanks Pankaj. You explained a lot in less time and easy manner.
- Ajay
Very good!
- fred
Stack memory is static, and heap memory is dynamic.(then read properly what is written) Second -_ why a method always contain 2 stack, if that method has no body. Third-- difference between iload and aload. How it is used in stack. If any one plz explain.
- Sanjeev
Hi Pankaj, Its very nice explanation you have given. But I have small query about below code, public class MemoryMgmt { static Integer a = new Integer(12); public static void main(String[] args) { Integer b = new Integer(12); int c = 12; System.out.println("a==b "+(a==b)); System.out.println("b==c "+(b==c)); System.out.println("a==c "+(a==c)); } } Can you please explain the memory allocation, where those variables are stored in memory.
- Santhosh
It’s very easy to understand. can you please notify which one is best? Stack or Heap
- Tamil
Thank you !
- Eric Wang
Its very nice explanation.
- Narendar
if we declare a variables in static method then wether it stores on heap or stack. Please explain me.
- Murugesh
Thanks pankaj that was very useful. I have related question if you could help. I have a PatriciaTrie list that holds item but there is not limit to the no of item . so when the item size is huge it throws Java heap error . there no way to increase it any more using -Xms am-Xmx . the only thing is that should be cached and proper message to be shown to the user (now it gives me a internal error which is not useful to the user). But the problem is i am not able to catch this exception. Any suggestions.
- sanjay
nice!
- Rajat
wow, I’m impressed, looks like one of the best examples I’ve seen so far (and I’ve seen quite a few).
- Lukasz
Great explanation . I feel the following link would complete this topic. https://www.mkyong.com/java/find-out-your-java-heap-memory-size/
- Parjanya Roy
nice tutorial thanks
- chandan
Very nice Example…good
- Jitendra Nandiya
Very Nice Explanation … Thank you
- lova