Java Garbage Collection: Mechanism and Best Practices

Rumman Ansari   Software Engineer   2024-07-04 03:48:21   7321  Share
Subject Syllabus DetailsSubject Details
☰ TContent
☰Fullscreen

Table of Content:

Objects are dynamically allocated by using the new operator, you might be wondering how such objects are destroyed and their memory released for later reallocation.

In C/C++, programmer is responsible for both creation and destruction of objects. Usually programmer neglects destruction of useless objects. Due to this negligence, at certain point, for creation of new objects, sufficient memory may not be available and entire program will terminate abnormally causing OutOfMemoryErrors.

In Java destruction of object from memory is done automatically by the JVM. When there is no reference to an object, then that object is assumed to be no longer needed and the memory occupied by the object are released. This technique is called Garbage Collection.

In C++, dynamically allocated objects must be manually released by use of a delete operator. Unlike C++ there is no explicit need to destroy object.

Can the Garbage Collection be forced explicitly ?

No, the Garbage Collection can not be forced explicitly. We may request JVM for garbage collectionby calling System.gc() method. But This does not guarantee that JVM will perform the garbage collection.

Advantages of Garbage Collection

  1. The programmer doesn't need to worry about dereferencing an object.
  2. Increases memory efficiency because garbage collector removes the unreferenced objects from heap memory
  3. decreases the chances of the memory leak.
  4. It is done automatically by JVM so we don't need to make extra efforts.

How can an object be unreferenced?

There are many ways:

  • By nulling the reference
  • By assigning a reference to another
  • By anonymous object etc.
  • Isolating a Reference

1) By nulling a reference:

Now, all we are looking forward to do here is to nullify the references to an object and once there are no reachable references the object looses its importance and is no longer needed thus becomes eligible for Garbage Collection.

ClassName cs =new ClassName();  
cs=null;  
 
Employee e=new Employee();  
e=null;  
Program:
public class RefrenceGarbageDemo{

public static void main(String [] args) {
	StringBuffer greet = new StringBuffer("atnyla");
	System.out.println(greet);
	greet = null;
	}
}
Output:
hello
Press any key to continue . . .

Here, in the above given example code we can see that before the reference to the StringBuffer object "atnyla" is removed or nulled i.e. greet is set to null there can be seen on the console the print "atnyla" but it more refers to "atnyla" after greet = null;

2) By assigning a reference to another:

ClassName cn =new ClassName(); 
ClassName cs =new ClassName(); 
cn=cs;  //first object referred by cn is available for garbage collection
 
Employee p1=new Employee();  
Employee p2=new Employee();  
p1=p2;//now the first object referred by p1 is available for garbage collection   
Program:

Another way in effect to remove the reference to a particular object and making it eligible for Garbage Collection is to set the reference variable which currently refers to it to a new object. Thus, re-assigning the reference variable. Let’s have a look at the following code:

class RefrenceGarbageDemo{

public static void main(String [] args) {
	StringBuffer greet = new StringBuffer("hello");
	StringBuffer greetNew = new StringBuffer("goodbye");
	greet = greetNew;
	System.out.println(greet);
	}
}
Output:
goodbye
Press any key to continue . . .

3) By annonymous object:

 new ClassName();  
 
new Employee();    
Program:
class RefrenceGarbageDemo{

public static void main(String [] args) { 
	System.out.println(new StringBuffer("hello"));
	}
}
Output:
hello
Press any key to continue . . .

4) Isolating a Reference:

 
ClassName r; 

ClassName r2 = new ClassName ();
ClassName r3= new ClassName (); 
r2.r = r3;
r3 = null;
 
Referen r;
 
Referen r2 = new Referen ();
Referen r3= new Referen ();
 
r2.r = r3;    
r3 = null;
Program:

This time we are not removing the references but just isolating them. Consider a case where a reference to an object is also used to refer to another reference to the same object. Now imagine that two such instances exist and that they refer to each other. If all other references to these two objects are removed, then even though each object still has a valid reference, there will be no way for any live thread to access either object. When the garbage collector runs, it will remove such objects.

public class Referen {
Referen r;

public static void main(String args[]) {
	Referen r2 = new Referen ();
	Referen r3= new Referen ();
	Referen r4= new Referen ();

	r2.r = r3;
	r3.r = r4;
	r4.r = r2;
	r2 = null;
	r3 = null;
	r4 = null;
 }
}
Output:
Press any key to continue . . .

However, we must always keep this in mind that the garbage collection is all not all in our control and how JVM works for it and selects the algorithm is all left to JVM’s discretion.