Memory Management in Java

Memory Allocation in Java
Memory Allocation in Java

Computer memory is a physical space required for storing data. It can be a temporary memory (like RAM) or permanent memory (Hard Disk). Memory as a resource is fixed and limited and hence a very crucial for programmers. The lesser memory a program requires to run without compromising its performance and speed, the better it is! In the following article, we will understand how memory is managed in Java.

How is memory organised in Java?

At a basic level, you can consider program memory to be divided into two chunks. Stack and Heap. You can think of a stack as a small memory and heap as a large memory space. Primitive datatype variables and reference variables to objects on heap are stored in the stack in which objects are stored in heap.

For Example: Consider the following code snippet

String name= “Naaz”;
int age =20;

Here, String is an object, therefore stored on the heap. Its reference- name variable is stored on the stack. Suppose the String “Naaz” is stored at memory address 540 in heap, so name variable will contain 540. Age is a primitive data type int, therefore stored on the stack.

Let us take one more example- Consider the code snippet below

public static void main(String[] args){

ArrayList myShoppingList = new ArrayList ();
myShoppingList.add (“pen”);
myShoppingList.add (“notebook”);
}
}

At the start of this program, we have an empty stack and heap. Main method contains a parameter which is an array of strings called args and this is the first item on the stack.

the first line in the main method

ArrayList<String> myShoppingList =new ArrayList <String>().

new keyword means find space on the heap large enough to store this object. And reference this new object through the variable myShoppingList. The variable myShoppingList contains the address of the Shopping List object on the heap.

  • myShoppingList.add (“Pen”) creates a String object with value “pen” on the heap and stores its address at zeroth index of ArrayList. It is same as writing.
  • myShoppingList.add (new String(“Pen”)). Note that there is no change on the stack on this line.

Similarly, the next line creates one more string object with value “notebook” and puts it at index 1 of the Array List.

Why are stack and heap designed so?

The stack is used for data that has a short lifetime- local variables or primitive data variables. Heap is used for data that has a longer lifetime like objects that need to be shared by various functions or code blocks. If you look at the physical memory amount allocated to heap and stack, heap memory is massive compared to stack memory.

Every thread has its own stack. Heap memory is shared across all threads. In an application, there is one heap that is shared across all threads and there are multiple stacks, one for each thread. By placing objects on the heap, it makes it easy to pass them around threads and code blocks in the application.

To summarise, following are the differences between stack and heap:

How is memory managed in Java?

In C, C++, Visual Basic, the programmer has access to the memory. He is responsible for both allocations of memory/creation of objects and deallocation of memory/destruction of objects. If the programmer doesn’t take care of freeing up the memory of objects that are no longer required, at some point of time sufficient memory may not be available and the program may run out of memory and crash.

This situation when the programmer has not cleared the memory of objects that are no longer required is called a memory leak. Also, note that in languages like C, C++, the programmer can create objects both on the stack and or heap. In Java, objects cannot be created on Stack memory. This limitation was placed to move the responsibility of deletion of objects from the programmer to the Java Virtual Machine (JVM) and make the process of freeing up memory automatic. (We will understand what a JVM is in the article below).

In Java, memory leaks are avoided because of two main reasons-

  • Garbage Collection
  • Java runs on Virtual Machine

What is Garbage Collection

The idea of garbage collection is that programmers ask for object creation (on the heap) but do not need to free them when their work is over. An automatic process keeps track of heap and deletes the objects which are no longer needed. It is done by a simple method: Any objects on the heap which cannot be reached through a reference from the stack are eligible for garbage collection.

For example: Consider the following scenario where there are two String objects on the heap.

Since there is no reference of String object with value “Naaz” on the stack, it is eligible for garbage collection. So, the main objective of garbage collection is to clear memory of objects on the heap that are “unreachable” from the Stack. Note that memory leak is still possible if an object has a reference on Stack even if it will never be used again. This situation is called “Soft Leak”.

So, to make the object available for garbage collection, the programmer can –

  • Explicitly set the value of the reference variable to NULL when the object is no longer required.
  • Re-assign the reference variable to point to another object.

What is a Virtual machine and how does it help in solving the issue of memory leaks?

Whenever you create an object using the new keyword, you are not taking memory from the operating system directly. The memory is acquired by the Virtual Machine. The virtual machine is a computer program written in C. It is used to run Java applications. This program among other things controls the allocation and freeing of memory from the operating system. It is safe to assume that designers of the Virtual Machine have ensured there are no memory leaks in its implementation.

The variables on stack are cleared by the JVM whenever a closing curly brace for the code block in which the variable is declared is encountered i.e. when the variable goes out of scope. The variables/objects on heap are cleared by the JVM whenever they become unreachable i.e. cannot be reached from a reference on the stack.

When object eligible for garbage collection, it may not be destroyed immediately by the garbage collector. Whenever JVM runs the Garbage Collector program, only then the object will be destroyed. 

The programmer can also explicitly request Java Virtual Machine (JVM) to run the garbage collector by using the following two methods:

  • system.gc() method
  • runtime.getruntime().gc() method

Now a lot of things would start making sense. Like why we need to create an object using the new keyword in Java or what is the work of the so much talked about JVM and garbage collector and how they came to be. We understand what goes behind the scenes for allocation and deallocation of memory.

To read more about Java, click here.

By Vidhi Agarwal