Garbage Collection in Java

In this article, we will learn about Garbage Collection in Java. Let’s start!!!

Garbage Collection in Java

The concept of “garbage collection” plays an indispensable role in managing memory. Removing unwanted memory allocation from the CPU makes the storage be handled efficiently. When this process takes place without the help of a programmer inputting several lines of code, it becomes even more competent.

However, before moving further into the topic, here are a few essential terms:

1. Heap: It is the logical area where all the objects are present. The heap implements tasks such as relocation and reorganization of objects in memory.

2. Garbage: As the name suggests, it is the unwanted portion in a program. To be precise, garbage is the memory that the objects might use in earlier cases but is no more useful.

3. JVM: The process in Java that manages the memory by deleting the unused objects is known as garbage collection. This frees up the memory space created on the heap. The garbage collector is specific in removing the objects that are not in use will be of no use in future.

Why is garbage collection essential?

A common mistake is that no programmer cares about deleting the unused memory of the objects. This might seem like an unwanted process, but the problem strikes when there is no required amount of memory left, and OutOfMemoryErrors start to occur.

How does Java tackle this when compared to C or C++?

When it comes to other languages like C or C++, the creation and destruction of the objects lie in the programmer’s hands. The free() in C and delete() in C++ does this task. As discussed earlier, the destruction of the objects is not given importance in all instances. This negligence will lead the program to be improperly terminated during the runtime.

In Java, this burden is reduced by a garbage collector process, as it destroys unused and unreachable objects. Therefore, the programmer need not manually free up the memory space. This makes Java more memory-efficient when compared to C and C++.

Working of Java garbage collection:

Java garbage collection is a default process that automatically takes place without the involvement of the programmer. The garbage collection implementation is present in the JVM. The JVM takes care of the garbage collection process according to its requirements. The most common JVM that executes this process is Oracle’s HotSpot. It provides a highly robust and mature set of garbage collection options.

The HotSpot consists of various garbage collectors with different use cases. Firstly, the unreferenced objects are identified and denoted as ready for garbage collection. Secondly, these marked objects are deleted. Sometimes after the garbage collection process, the memory can be compacted. This paves waves for easy memory allocation for the new set of objects.

HotSpot’s garbage collectors come under the generation garbage collection strategy. Here, the objects are categorized according to their age.

1. Young Generation: The objects that we create a new start in Young Generation. This is further categorized into an Eden space. Here, all the objects start and two Survivor spaces move from Eden after surviving a garbage collection. When this process of collecting objects from the young generation takes place, it is known as garbage collection.

2. Old Generation: Here, the objects that live long are readily moved from the Young generation to the Old Generation. When this process of collecting objects from the permanent generation takes place, it is a major garbage collection event.

3. Permanent Generation: Metadata such as classes and methods are piled in Permanent generation. Classes that are no more used are garbage collected from the permanent generation.

Types of Garbage Collection in Java:

1. Minor Garbage Collection: It is also known as incremental garbage collection. It occurs in the presence of unreachable objects being removed from the young generation heap.

2. Major Garbage Collection: It is also known as full garbage collection. It occurs when the objects that endured the minor garbage collection and were copied into the old memory heap are eradicated. This is likely to take place less frequently.

Types of Garbage Collectors in java:

1. Serial Garbage Collector: The garbage collection process takes place in a single thread in a serial order. It is mostly used in simple programs. The XX:+UseSerialGC JVM argument activates it.

2. Parallel / Throughput Garbage Collector: It is the default garbage collector opted by the JVM. It uses multiple threads for major garbage collection. Most likely to execute long processes. To activate the Parallel GC, the –XX:+UseParallelGC JVM argument must be executed.

3. Concurrent Mark Sweep (CMS) Garbage Collector: It uses multiple threads to first scan the unwanted instances to eradicate them. It allows the garbage collection thread to execute concurrently while the application’s thread is running. The –XX:+UseParNewGC or the -XX:+ParallelCMSThread=<n> JVM argument activates it.

The Mark Sweep Algorithm is used for undergoing garbage collection. There are two phases: the mark phase and the sweep phase.

  • Mark Phase: In this phase, all the threads, native handles and garbage collection is marked as live. All the necessary objects are marked separately, and the rest are considered garbage.

Mark Collection Algorithm:

Mark(root)
If markedBit(root) = false then 
markedBit(root) = true
For each v referenced by a root
Mark(v)
  • Sweep Phase: Here, the heap looks for the gaps between the live objects. These gaps are put into a free list, making them available for new object allocation.

Sweep Collection Algorithm:

Sweep()
For each object p in a heap
If markedBit(p) = true then
markedBit(p) = false
else
heap.release(p)

This process is also called tracing garbage collectors as it traces the objects.

Example

1. Marked bits set as false.

2. Reachable objects set as true.

3. Non-reachable clear from the heap.

The two improvised versions of mark and Sweep are:

  • Concurrent Mark and Sweep
  • Parallel mark and Sweep

a. Concurrent Mark and Sweep:

At this phase, the threads continue running effortlessly when the garbage collection is taking place. It has further categories:

  • Initial marking: While the threads are on a pause, the initial marking is done to find the root set of live objects.
  • Concurrent marking: Here, the references from the root set are followed to mark the live objects. This takes place while the thread is running.
  • Precleaning marking: This also takes place while the threads are running. It helps in finding the recent changes made by the concurrent marking.
  • Final marking: All the changes made by the precleaning marking step can be found in the final marking stage.

b. Parallel Mark and Sweep:

This method uses all the available CPUs to collect the garbage more efficiently. It is also termed as a parallel garbage collector. During this process, the threads will be paused.

Advantages of Mark and Sweep:

  • It is a recurring process.
  • It has an infinite loop.
  • There are no additional overheads performed.

Disadvantages of Mark and Sweep:

  • The normal program execution will be paused when the garbage collection is taking place.
  • It runs various times on a program.

4. Garbage First (G1) Garbage Collector: The G1 GC is helpful when there is a large chunk (more than 4GB) of garbage to clear. It is executed by dividing the heap into equal partitions to collect the garbage in prioritized order. The –XX:+UseG1GC JVM argument activates it.

How does JVM denote certain objects as garbage?

The primary characteristic of garbage is that it must be unreferenced. In Java, there are many ways the objects can be unreferenced. They are as below:

1. Nullifying the reference:

Student s = new Student();

s = null; // Here, the object is being declared null, this makes it a garbage value.

2. Assigning the reference to another object:

Student s1 = new Student();

Student s2 = new Student(); // as another object s2 is introduced for the Student(), the first declared object, s1 is considered as a garbage.

3. Making the object anonymous:

new Student(); // as no certain object is assigned to the method; it stays anonymous.

In the above-explained ways, the object becomes garbage.

Requesting JVM to run the garbage collector:

The garbage collection process does not take place as soon as the garbage is allocated. Therefore, the execution of the JVM to destroy the object is indeterminable. But, there are a couple of methods to provoke the garbage collector to perform this action.

1. System.gc() method:

The gc() method is static in the system, which helps request the JVM run the Garbage Collector.

Runtime.getRuntime().gc() method: Here, the Runtime class provides the permission for the application to interface with JVM. Further, due to the presence of the gc() method, the JVM requests the Garbage Collector to run.

Therefore, the gc() method in the System and Runtime classes helps the programmer to invoke the Garbage collector.

Simple code to execute garbage collection in Java:

public class FirstCode
{
public void finalize() {System.out.println(“The garbage object found”);}
public static void main(String args[]){
FirstCode fc1 =new FirstCode();
FirstCode fc2 =new FirstCode();
fc1 = null;
fc2 = null;
System.gc();
}
}

Output

The garbage object found
The garbage object found

The line “The garbage object found” is printed twice as there are two garbage values nullified in the above code.

2. finalize():

· In some instances, the finalize() method is overridden to clean various tasks like closing database connection and so on.

· It is invoked only once for an object when it is collected as garbage.

· The objects that are created without the keyword ‘new’ use the finalize() method for the cleanup process.

· In case of an uncaught exception is thrown by it, the exception is ignored.

Real world example of Garbage Collection:

Situation: Let us take a real-world example of counting the number of students studying in a school. We can implement the concept of garbage collection to find the result.

This is the actual task that you will be assigned:

1. An ID for storing unique ID for every student.

2. Student Name.

3. Student age

The methods we require are:

1. A parameterized constructor to initialize student name and age. The ID is should be initialized in this constructor.

2. A method show() to display ID, name, and age.

3. A method showNextId() to display the ID of the next student.

The below code is when the garbage collector in Java will code like:

class Student{
private int ID;
private String name;
private int age;
private static int nextId = 1;

public Student(String name, int age){
this.name = name;
this.age = age;
this.ID = nextId++;
}
public void show(){
System.out.println(“Id: ” ID + “Student Name:” +name + “\n Age: ”+age);
}
public void showNextId(){
System.out,println(“The ID of the next student is: ”+nextId);
}
} 
class FirstCode{
public static void main(String args[]){
Student A = new Student(“John”, 16);
Student B = new Student(“Kevin”, 14);
Student C = new Student(“Abraham”, 13);
A.show();
B.show();
C.show();
A.showNextId();
B.showNextId();
C.showNextId();
{
Student S = new Student(“Martin”, 16);
Student S1 = new Student(“Liya”, 14);
S.show();
S1.show();
S.showNextId();
S1.showNextId();
}
S. showNextId();
}
}

Output:

Id: 1
Student Name: John
Age: 16
Id: 2
Student Name: Kevin
Age: 14
Id: 3
Student Name: Abraham
Age: 15
The ID of the next student is: 4
The ID of the next student is: 4
The ID of the next student is: 4Id: 4
Student Name: Martin
Age: 16
Id: 5
Student Name: Liya
Age: 14
The ID of the next student is: 6
The ID of the next student is: 6
The ID of the next student is: 6

The right way to get the output:

In this situation, the garbage collector(gc) has 2 objects as free. To decrement the nextId, the gc(garbage collector) will call the finalize() method only when the programmers override it into the class.

Now, we must request the gc(garbage collector) and for this, the following three steps should be written before closing brace of sub-block:

1. Set references to null(X = Y = null;)

2. Call, System.gc();

3. Call, System.runFinalization();

Here is the correct code to count the number of students:

class Student{
private int ID;
private String name;
private int age;
private static int nextId = 1;

public Student(String name, int age){
this.name = name;
this.age = age;
this.ID = nextId++;
}
public void show(){
System.out.println(“Id: ” ID + “Student Name:” +name + “\n Age: ”+age);
}
public void showNextId(){
System.out,println(“The ID of the next student is: ”+nextId);
}
protected void finalize(){
--nextId;
}
} 
public class FirstCode{
public static void main(String args[]){
Student A = new Student(“John”, 16);
Student B = new Student(“Kevin”, 14);
Student C = new Student(“Abraham”, 13);
A.show();
B.show();
C.show();
A.showNextId();
B.showNextId();
C.showNextId();
{
Student S = new Student(“Martin”, 16);
Student S1 = new Student(“Liya”, 14);
S.show();
S1.show();
S.showNextId();
S1.showNextId();
X = Y = null;
System.gc();
System.runFinalization();
}
S. showNextId();
}
}

Output:

Id: 1
Student Name: John
Age: 16
Id: 2
Student Name: Kevin
Age: 14
Id: 3
Student Name: Abraham
Age: 15
The ID of the next student is: 4
The ID of the next student is: 4
The ID of the next student is: 4Id: 4
Student Name: Martin
Age: 16
Id: 5
Student Name: Liya
Age: 14
The ID of the next student is: 6
The ID of the next student is: 6
The ID of the next student is: 6

Monitoring Java Garbage Collection:

The garbage collection causes some disrupts in the performance of the application. As this process is inevitable in Java, it is vital to make sure that the garbage collection process is not functioning more than the required limit.

Therefore, monitoring the garbage collection is given importance. Generally, the time spent on garbage collection must be less than 5%. This allows other functions of the applications to run smoothly without lags.

Metrics to monitor Garbage Collection in Java:

Certain metrics give an idea about the garbage collection activity. Some of them include:

  • The instance when the garbage collection took place.
  • JVM’s involvement in garbage collection.
  • Frequency of the garbage collection process.
  • Amount of memory freed.
  • Duration for how long the garbage collector is running.
  • Type of garbage collection taking place.
  • JVM’s CPU utilization.

Java Garbage Collection best practices:

In the case of small and simple applications, the programmers do not give importance to garbage collection. But, to acquire a good skillset in Java, knowing the concept of Garbage collection and how it works is important.

Some of the major points that a programmer must understand are, that garbage collection is nondeterministic and it is unpredictable. We can also provide System.gc() or Runtime.gc() in the code to make the garbage collector run. But there is no surety that this will definitely take place.

The wiser approach is to tune the garbage collection is by setting the flags on the JVM. These flags adjust the garbage collector that can be used, the minimum and maximum heap size, heap section sizes, and many more. Considering the nature of the application would be helpful in applying the tuning settings.

For example, though the Parallel garbage collector is efficient, it enables the “stop the world” event to frequently. This makes it apt for the backend processes where long pauses for garbage collection are acceptable.

Whereas, the CMS garbage collector helps in minimizing the garbage collector process. This makes it better suited for GUI applications as responsiveness is important in these cases. Added fine-tuning can take place by modifying the heap size or sections. It also includes measuring the garbage collection efficiency with tools like jstat.

Important concepts related to Garbage Collection in Java

1. Unreachable objects

When an object does not have any reference, it is denoted as unreachable. In addition, the objects that belong to the part of isolation are also unreachable.

Integer i = new Integer(5);

2. Eligibility for garbage collection

An object becomes eligible for garbage collection when it is unreachable. After i = null, the integer object 5 present in the heap area, is ready for garbage collection.

Ways to make an object eligible for garbage collection

Though the programmer need not take the accountability to destroy the useless objects, it is better to make an object unreachable when it is no longer required.

To make an object eligible for garbage collection, we can follow any one of the four following ways:

  • Nullify the reference variable
  • Re-assign the reference variable
  • Create an object inside the method
  • Island of isolation

Advantages of Garbage Collection

  • The Garbage collection concept in Java relieves the programmer from deallocating the memory space by deleting the objects when not in use.
  • This is now a basic requirement in upcoming programming languages and various platforms.
  • The Java Virtual Machine (JVM) undertakes this process without the invoke of a programmer.
  • As the programmer is not required to create code for it, the writeability of the system is reduced.

Disadvantages of Garbage Collection

  • Even though the garbage collector runs on a separate thread, a slight difference in the performance occurs.
  • Another major disadvantage is that the programmer will not be aware of when the garbage collector will be invoked and how long it will run.
  • This further leaves the programmer with limited control over CPU scheduling to reclaim memory space.
  • Sometimes, this process would continue for too long to even be noticed. This makes it disruptive in various real-time environments.
  • There is a high possibility of memory management errors like memory leaks.
  • The garbage collectors also pause the entire program in the event of looking for garbage objects.

Conclusion

This was all about the garbage collection in java. When the disadvantages of garbage collection are monitored wisely, the programmer can reap the most assistance out of it.

Leave a Reply

Your email address will not be published. Required fields are marked *