What Is Garbage Collection In Java And How Does It Work

This Tutorial Explains what is Garbage Collection in Java and how does Garbage Collector work. You will also learn about Algorithms for Garbage Collection:

The readers who are knowledgeable in C/C++ must be aware that it is the responsibility of the programmer to create and delete the objects in C/C++.

Serious errors arise if the programmer forgets to destruct the objects created. This is because failing to destruct the objects may cause “OutOfMemory” errors, memory leaks, etc.

This situation is completely taken care of in Java as there is no need for a programmer to keep a track of the objects. Java takes care of object destruction for us through automatic garbage collection.

=> Visit Here To Learn Java From Scratch.

Garbage collection in Java

The process by which the objects that are no longer in use are removed from the heap memory is called “Garbage Collection”. The garbage collection technique is a part of memory management in Java.

Thus in Java, the Garbage Collector destroys all the objects that are not in use anymore.

What Is A Garbage Collector In Java?

Garbage Collection in Java is managed by a program called Garbage Collector.

Garbage Collector can be defined as a program that is used to manage memory automatically by handling the object de-allocation.

We know that in Java language, the new objects are created and allocated memory using the new operator. The memory allocated to an object using a new operator remains allocated until the references are using this object.

As soon as the references cease to exist, the memory that the object occupies is reclaimed. Java then handles the de-allocation or destruction of objects automatically and we need not explicitly destroy the object.

This technique is the Garbage Collection technique in Java where the programmers need not handle the deallocation of objects explicitly.

Note that if the programs do not de-allocate the memory when the objects do not need it then eventually there will be no memory left to allocate and the programs will crash. This situation is called a memory leak.

The garbage collector always runs in the background on a daemon thread. Garbage Collector is considered as the best example of the daemon thread.

Garbage Collector runs intending to release the heap memory. It does this by destroying the objects that are “unreachable”.

What Is An “Unreachable” Object?

An object becomes unreachable when there is not even a single reference associated with it.

Consider the following piece of code:

 Integer ref_obj = new Integer (5); //ref_obj is a reference to Integer

 ref_obj = null; //Integer object now becomes unreachable

As seen from the above code, an object is reachable as long as a reference is associated with it. The moment the reference association is removed (a setting reference to null in the above case) the object becomes unreachable.

When an object becomes unreachable, it becomes eligible for Garbage Collection (GC).

How can we make an object eligible for GC?

Though the programmer is not required to destroy the objects as they are taken care of by GC, at least the programmer can make these objects unreachable when they are no longer required.

By doing this, GC will collect the unreachable objects and destroy them.

There are some ways to make an object eligible for GC by making it unreachable.

They are:

#1) Nullify The Reference

Given a reference assigned to an object, if this object is no longer needed then assign the reference to null.

Student s = new Student ();

s = null;

When s is set to null, the Student object becomes unreachable.

#2) Re-assign The Reference

This is another way of making the objects eligible for GC.

Consider the following code.

Student s1 = new Student ();

Student s2 = new Student ();

s1 = s2;

Now as we have assigned s1 to another object, the Student object referenced by s1 is dereferenced.

#3) Create An Anonymous Object

By creating an anonymous object we can make the objects eligible for GC.

We can create an anonymous object as shown below:

new Student();

Once we make the objects eligible for GC, these objects may or may not be destroyed immediately by GC. This is because we cannot explicitly force the GC to execute as and when we want.

When Does The Garbage Collector Run?

It is up to the JVM to run the Garbage Collector program. When JVM runs the Garbage Collector, the unreachable objects are destroyed. But still, we cannot guarantee when the JVM will run.

Although we cannot force the GC to execute, we can very well request for a Garbage Collection.

The GC can be requested using any of the following methods.

#1) System.gc(): The System class of Java provides a static method gc () using which we can request the JVM to run Garbage Collector.

#2) Runtime.getRuntime().gc(): Like System.gc (), we can also use the gc () method of “Runtime class” to request JVM to run Garbage Collector.

Note: There is no guarantee that the Garbage Collector will run after a request from these two methods.

Finalization

Finalization is performed by Garbage Collector just before destroying the objects. As a part of the finalization technique, the Garbage Collector calls the finalize() method on the object. The finalize() method is used to perform cleanup activities.

The finalize( ) method is provided by the “Object” class and has the following prototype.

 protected void finalize () throws Throwable

The finalize() method is invoked whenever the object is garbage collected

Note: The Garbage collector only collects the objects that are created using the new keyword. For other objects, we have to use the finalize () method to perform the cleanup.

The below program shows a simple Garbage Collection in Java.

class TestGC{  
 @Override
    // finalize method: called on object once  
    // before garbage collecting it 
    protected void finalize() throws Throwable 
    { 
        System.out.println("Garbage collector called"); 
        System.out.println("Object garbage collected : " + this); 
    } 
}
class Main{
 public static void main(String args[]){  
  TestGC gc1=new TestGC();  
  TestGC gc2=new TestGC();  
  gc1 = null;  //nullify gc1
 
  System.gc();  //request for GC to run 
  gc2 = null;  //nullify gc2
  Runtime.getRuntime().gc(); //request for GC to run
 }  
}

Output

Garbage collector in Java

In the above program, we have created a class TestGC. In this class, we have overridden the finalize() method. Then in the main class, we create two objects of TestGC class. First, we nullify an object and call the System.gc() to request Garbage Collector.

Next, we nullify the second object and call method Runtime.getRuntime.gc() to request Garbage Collector. The output shows the finalize method output twice thereby indicating that the Garbage Collector ran twice.

Note: Though we have got this output, it is not guaranteed that every time we will get the same output. It completely depends on JVM.

How Does Garbage Collection Work In Java?

In this section, we will see how Garbage Collection works in Java.

During garbage collection, the Garbage Collector looks up the Heap memory and then “marks” the unreachable objects. Then it destroys them.

But the problem arises when the number of objects increases. As the objects increase, the time taken for Garbage Collection also increases as it looks for unreachable objects. However, it doesn’t affect too much as most of the objects have short life-span.

The behavior above is called “Generational Garbage Collection” and is supposed to improve JVM performance. In this approach, the entire Heap space is divided into – Young Generation, Old or Tenured Generation, and Permanent Generation.

#1) Young Generation Heap Space: All the new objects are created in this space. Once the space is full, Minor GC takes place wherein all the dead objects are destroyed. The minor GC process is fast and quick as most objects are dead. The objects surviving the young generation are moved to the older generations.

#2) Old Generation Heap Space: This generation stores objects that survive for long. When the threshold age set for the young generation is met, the object is moved to the old generation. When the old generation space is filled, a Major GC is performed.

Major GC is slow as objects involved here are live objects. Sometimes the entire Heap space that includes young, as well as old generations, is cleared. This is called “Full GC”.

#3) Permanent GenerationL Till Java 7 there used to be a Permanent Generation (Perm Gen). The Perm Gen held metadata was used by JVM. JVM used this metadata to describe classes and methods used in the application. The Perm Gen was removed in Java 8.

Java 8 Garbage Collection: Perm Gen And Metaspace

We have already mentioned about Perm Gen space that was present till Java 7. However, now in Java 8, the JVM represents the class metadata using the native memory called “Metaspace”.

Apart from Metaspace, there is a new flag called “MaxMetaspaceSize” that limits the memory used for class metadata. If no value is specified for MaxMetaspaceSize, then the Metaspace resizes it at runtime according to the application demand.

When class metadata space reaches MaxMetaspaceSize, the Metaspace GC is triggered. When there is excessive Metaspace GC, it indicates memory leak of classes, classloaders, etc. as well as inadequate sizing.

Garbage Collection Algorithms In Java

There are various ways in which the Garbage Collection is performed. In this section, we will present four such ways or algorithms for Garbage Collection in Java.

Serial GC

Serial GC is the simplest GC algorithm. It mainly works on small heap sizes and single-threaded systems. While working, Serial GC freezes all the applications.

To turn on Serial GC, we can use the following JVM Option.

java –xx:+UseSerialGC –jar Application.java

The above command can be given in the command line. Here Application.java is a file for which serial GC is to be enabled.

Throughput/Parallel GC

THE Parallel GC algorithm is the default one in JDK 8. This algorithm uses multiple threads to scan the heap space and compaction. This algorithm is suitable mostly for applications that can handle thread pauses and optimize the CPU overhead.

One disadvantage of parallel GC is that while performing minor or full GC, the algorithm pauses the application threads.

The CMS Collector

The CMS stands for “Concurrent Mark Sweep”. This algorithm makes use of multiple concurrent threads to scan the heap (mark) to identify unused objects and recycle (sweep) them. The CMS collector has a mode Stop-The-World (STW).

The collector goes in this mode in two scenarios:

  • When objects belonging to the old generation can be reached from static variables or thread entry points. So this mode is on during the initialization of initial root markings.
  • When the algorithm is running concurrently, the application changes the state and forces the collector to go back to make sure that the correct objects are marked.

The CMS collector however may suffer from “promotion failures”. So what is a promotional failure? If the objects from the young generation space are moved to the old generation, and the collector has not made enough space for these objects in the old generation heap space then a promotional failure will occur.

To prevent promotional failure, we may provide more background threads to the collector or provide more heap size to the old generation.

The G1 Collector

The G1 Collector is the “Garbage-First” Collector. It is designed for heap sizes of more than 4GB. Based on the heap size, it divides the heap size into regions of sizes ranging from 1MB to 32MB.

G1 collector marks the objects depending on the liveliness of the objects throughout the heap. After this marking phase, G1 is aware of the empty regions. Thus it collects the unreachable objects from these regions thereby freeing a large amount of space. Hence it is named as Garbage-First as it collects regions containing garbage first.

It also meets the user-defined pause time target by using a pause prediction model by selecting the number of regions to collect depending on the specified pause time target.

Advantage Of Garbage Collection

  • Garbage Collection makes memory management in Java efficient as it removes unreferenced objects from the heap memory without the interference of the programmer.
  • As Garbage collection is automatic and is a part of JVM, no extra efforts are needed from the programmer to reclaim memory or destruct objects.
  • The programmer need not write any specific code to de-allocate the memory and delete objects as done in C/C++.

Frequently Asked Questions

Q #1) What is the role of a Garbage Collector?

Answer: In Java, the Garbage Collector is the main party in the memory management and is tasked with collecting the unreachable objects and reclaiming the memory.

Q #2) What do you mean by Garbage Collection?

Answer: Garbage collection is the technique by which memory is managed automatically by reclaiming the unused memory. It is a feature present in programming languages like Java, due to which the programmers need not keep track of the unused objects and destroy them. It is done automatically using Garbage Collection.

Q #3) Who is responsible for Garbage Collection in Java?

Answer: Memory management of Java has the responsibility of Garbage Collection.

Q #4) How can we prevent Garbage Collection in Java?

Answer: As the Garbage Collector does not reclaim the memory of variables/objects that are alive, the best way to prevent Garbage Collection is to keep using variables/objects throughout the program.

Q #5) How can you make sure that an object is Garbage collected?

Answer: An object is eligible for Garbage Collection when it is unreachable i.e. when no more references are referring to the object. Although we cannot force the Garbage Collector to run whenever we want, we can always request it to run using System.gc ().

Conclusion

The Garbage Collection in Java that we discussed in this tutorial is automatic and the programmer need not concern himself/herself about deleting the objects or variables allocated in the program.

Automatic Garbage Collection in Java is the most important feature of the language and is a part of memory management in Java.

Though Garbage Collection is performed by JVM and is out of the programmer's reach, we can always request the Garbage Collector to run using the gc () method of System and Runtime class.

In this tutorial, we have discussed the finalization process that is performed before the objects are destroyed by Garbage Collector. We have also discussed the process of the Garbage Collection in Java. Finally, we have discussed the various algorithms used by the Garbage Collector.

This completes our discussion on Garbage Collector in Java.

=> Watch Out The Simple Java Training Series Here.