In order to have a deep understanding of the Object Oriented Programming in Java or any other OOP language (like C#) you must know how things are managed internally by the Java process and by the JVM. Of course Java syntax and Java implementations of OOP principles are important but you will have a more clear image about the application resources, memory, performance, argument passing, threads and garbage collection if you put questions beyond How I do that ? or How I write that ?. The real questions should be How or Why it is happening like this ? (of course, at some point you should stop and move forward).
In this post I will describe how the application variables are managed, regarding where they are stored (Stack or Heap) and for how long.
Other topics that are part of this Java tutorial are accessible through Java 6 Tutorial – Contents
What is the Stack and the Heap
Keeping things simpler (if you know some assembler background you will see that this is a superficial approach) your application is processing data by storing it into memory areas in Random Access Memory. These areas are called:
Stack:
-
a memory space reserved for your process by the OS;
-
the stack size is fixed and it is determined in the compiler phase based on variables declaration and other compiler options;
-
it is important to establish that the stack is limited and its size is fixed (one the process has started, it can’t change the stack size);
-
most of the time, the stack it is used to store functions/methods variables (input arguments and local variables).
-
each method has its own stack (a zone in the process stack), including main, which is also a function.
-
a method stack exists only during the lifetime of that method: from the calling moment until the return moment;
Heap:
-
a memory space managed by the OS and used by processes to get additional space at run-time;
-
this area it is a global, meaning that any process can use it (of course, processes can’t read or write in another process Heap reserved area);
-
the role of this memory is to provide additional memory resources to processes that need that supplementary space at run-time (for example, you have a simple Java application that is constructing an array with values from console);
-
the space needed at run-time by a process is determined by functions like new (remember, it the same function used to create objects in Java) which are used to get additional space in Heap.
What is stored in Stack and in Heap
Based on previous rules, let’s analyze this simple Java application:
class Student{
int age; //instance variable
String name; //instance variable
public Student()
{
this.age = 0;
name = "Anonymous";
}
public Student(int Age, String Name)
{
this.age = Age;
setName(Name);
}
public void setName(String Name)
{
this.name = Name;
}
}
public class Main{
public static void main(String[] args) {
Student s; //local variable - reference
s = new Student(23,"Jonh");
int noStudents = 1; //local variable
}
}
In order to determine the minimum space (because we focus only on the important elements and we keep things as simple as possible) let’s analyze the Stack requirements. In the next paragraph I describe each method stack separately but in the end all these are placed on the same stack, the application stack.
We start with the main method because for a Java process everything begins and ends with main. The main local variables, or variables stored on its Stack are:
-
the args reference (it is an array of Strings);
-
the Student reference, named s;
-
the integer (4 bytes) value, named noStudents;
The default constructor local variables are:
-
the current created object reference, named this;
-
that’s all (remember: the object and its values are stored in Heap).
The second constructor, the one with arguments, local variables:
-
the reference of the current created object, named this;
-
the input argument, Age, an integer value
-
the input argument, Name, a String reference
The setName method local variables are:
-
the calling object reference, named this; (remember: each non-static class method it is called by an object and that object reference is passed to the method as this)
-
the input argument, Name, a String reference
As I said earlier, all these methods stacks are in fact, parts of a single applications stack. Each part exists during the function lifetime. If you analyze the order in which these methods are called you can define a bigger picture – the process call stack.
For the previous example, when the constructor with arguments it is executed, the call stack looks like this:
As you can see, from the previous image, the call stack is generated by all the active methods. Because the main method is the process entry point, it is the first method on the call stack. After this moment, each time a method is called, it will be placed on the call stack.
For the previous example, the call stack has the maximum size when it is called the setName method from the Student constructor.
In Heap there are stored all the values that are created using new operator, meaning mostly object values. So, for the previous example, the references are stored on the method stack and the objects are stored in Heap:
In the previous image, there are described the methods local variables, which are stored on their stack. Also, you can see that objects values (the Student and the String) are stored in Heap.
The Heap values are created by:
- the Student memory area in Heap is created by calling the new operator and the class constructor;
- the String value is created during the object initialization inside the class constructor.
What is the lifetime of variables from Stack and Heap
The general rule regarding the lifetime of variables is that they exist at least for the time you need them.
For stack variables, because they are on the method stack, they exist as long as the method is executed. Because main method is a special method (the process starts and ends with main) its local variables exist for the entire execution of the process. For other methods, their stack exists only from the moment we call the method until it ends (with a return or because of an exception).
The values in Heap (object values) exist as long as we have a reference that has the address of that memory area in Heap. If the Heap memory area can’t be reached through a reference (the reference does’t exist or it has another value/address), the Garbage Collector will release that space. (more on Garbage Collector in next tutorial).
Other types of variables, like the class static attributes, are managed in the same way,with the difference that they are stored on the process stack, before using that stack for methods stacks.
Other topics that are part of this Java tutorial are accessible through Java 6 Tutorial – Contents.
Well done guys.
The way you write is quite simple to understand and this article is quite useful.
Some problems happen because we don’t know how the things work inside the JVM. More articles about JVM would be welcome.
I really appreciated it.
Thanks for share it with us.
Very well written article. This is the best explanation of stack and heap concept that I have seen so far.
Hello,
I’m beginning to study Java, and OOP, in order to apply it to Android App Development.
Regarding the Default constructor, why isn’t coded:
this.name = “Anonymous”; ?
What does the
name = “Anonymous”; do?
And, in the explanation below, you say the the only local varable present in the const. method is the current created object reference, named ‘this’.
Then you say ‘that’s all (remember: the object and its values are stored in Heap).’ Isn’t Age a value (attribute) of the object? I’m confused there.
Hi Catia,
this.name = “Anonymous”; is equivalent to name = “Anonymous”; and both instructions have the same effect. They initialize the current object attribute with the “Anonymous” string value.
Java recommends using this reference all the time as it makes the code more readable.
Yes the only local variable present in the default constructor is the this reference. References are numeric variables that manage addresses to memory locations in Heap memory. The Student requires a memory area for its attributes (at least) and this area is in Java always in Heap. In order to access it and object attributes with need its address, which obviously is provided by this reference.
So in order to get to an object and its attributes (variables) you need a reference to it. Without the reference the object is useless because you can not reach it.
I hope this helps you clear you mind about this concepts. Anyway, this is something that requires some thinking and it takes a some time to understand.
OK, so this.age will create Objects of type Student, all initialized with the age 0, which is a a Primitive Data Type, and so not and Object Data Type (as String) which will cause you to have said that it is the only Local Variable? (Object Data Types can have the same scopes as the Primitive Data Types or are there any restrictions?)
This constructor will also initialize all Student objects with the name ”Anonymous”? The ‘s’ object reference is initialized using the 2nd constructor. Can you give an example of one initialized with the Defaut one, please.
Thank you
Always the constructor (a method) creates objects. The this.age instruction only sets the value for one of the object attributes.
It is correct, both constructors initialize the name attribute with the ”Anonymous” value. An example of using the default constructor (without arguments) is:
s = new Student();
awesome article
Nice article
Hello iam abdullah raza lakhan , so many students are confuse about stack and heap , iam just clear one thing stack and heap are part of memory ,look following example
class lakhan
{
int a =10;// it store on stack and call when program compile , because our variable store on stack , but temporary when program end it will end.
public static void main()
{
lakhan a=new lakhan()//this class object store on heap it will call execution of program ,i hope this basic example will out u }
}