top

Search

Java Tutorial

.

UpGrad

Java Tutorial

Garbage Collection in Java

Automatic memory management is implemented through a process known as garbage collection in Java, where manual memory deallocation is not required. Its purpose is to enhance the speed of applications and eliminate memory leaks by releasing memory occupied by unused objects.

The optimization of memory allocation and reduction of memory-related errors is achieved through garbage collection in Java, resulting in efficient utilization of resources. It relieves developers of memory management duties so that they can focus on the program's logic. The stability, scalability, and ability of Java to handle large-scale applications heavily rely on the presence of garbage collection.

Overview

This tutorial is a detailed guide to help you understand the in-depth concepts of garbage collection in Java. You will also learn about Java Virtual Machine, the advantages and disadvantages of garbage collection in Java, and how garbage collection works in Java.

What is Garbage Collection?

The primary goal of garbage collection in Java is to release heap memory by eliminating inaccessible objects. It constantly operates in the background and is an example of the Daemon Thread.

Programmers creating and destroying objects frequently forget to dispose of unused objects, which may result in insufficient memory to construct new objects. To prevent unexpected problems like abnormal termination of programs and OutOfMemoryErrors, garbage collection is put to use. 

How Does Garbage Collection in Java Work?  

Java uses an automated garbage collection method. Automatic garbage collection entails heap memory scanning to determine which objects are being used and which are not and removing the latter.

A referenced object, also known as an in-use object, signifies that a part of your program still holds a pointer to it. Once an object is no longer being used or referenced by any part of your program, the memory occupied by that object becomes available for reuse. It is not necessary for the programmer to specifically indicate objects for deletion. The JVM houses the garbage collection implementation. 

The JVM (Java Virtual Machine) keeps track of object references to find inaccessible objects (trash) and frees up memory for useful objects. Programmers can quickly destroy these objects with a garbage collector in Java.

Here is an example that will help you learn how garbage collection works:

public class Example {
    public static void main(String[] args) {
        // Create objects
        MyClass obj1 = new MyClass();
        MyClass obj2 = new MyClass();
        // Assign obj1 to null
        obj1 = null;
        // Invoke garbage collection explicitly
        System.gc();
        // Perform some other operations    
        // ...
    }
}
class MyClass {
    // Class definition
}

In this example, two MyClass objects, obj1, and obj2, are created. Afterward, obj1 is assigned the value null, making it unreachable. At this point, obj1 becomes eligible for garbage collection.

The System.gc() statement invokes garbage collection explicitly. While it is not necessary to explicitly call System.gc() (as garbage collection is automatically triggered by the JVM when needed), it can be used to suggest garbage collection at a specific point in the code.

Once garbage collection is triggered, it identifies that obj1 is no longer reachable and reclaims its memory. The memory can then be reused for future object allocations.

How Can an Object Be Unreferenced?

In programming, an object can become unreferenced when it is no longer connected to references. This renders the object inaccessible and essentially discarded. Multiple methods can be employed via which an object can be unreferenced. An object can be effectively unreferenced by employing these techniques, allowing for efficient memory management and preventing memory leaks.

By nulling the reference

The first approach entails making a reference null by assigning the special value "null," signifying that it no longer refers to any object. When all references to an object are set as null, the object becomes qualified for garbage collection. The first program we discussed is an example of using this technique.

By assigning a reference to another

Another way is by reassigning a reference to a different object. If no other references exist to the original object, it becomes unreferenced and can be disregarded

public class Example {
    public static void main(String[] args) {
        // Create objects
        MyClass obj1 = new MyClass();
        MyClass obj2 = new MyClass();
        // Assign obj1 to obj2
        obj1 = obj2;
        // Invoke garbage collection explicitly
        System.gc();
        // Perform some other operations       
        // ...
    }
}
class MyClass {
    // Class definition
}

In this example, two MyClass objects, obj1, and obj2, are created. Initially, obj1 and obj2 refer to separate objects in memory.

By assigning obj2 to obj1 (obj1 = obj2;), the reference obj1 now points to the same object as obj2. The previous object that obj1 was referring to becomes unreachable.

When garbage collection is triggered (either automatically by the JVM or explicitly with System.gc()), it identifies that the initial object referred to by obj1 is no longer reachable. Therefore, it becomes eligible for garbage collection, and its memory can be reclaimed.

The assignment of obj1 = obj2; does not directly cause garbage collection to occur. The reachability of objects in memory determines garbage collection. In this case, assigning a reference to another object indirectly affects the reachability of the original object, making it eligible for garbage collection.

By anonymous objects

Lastly, anonymous objects come into play. These objects are created without being assigned to a named reference and are often used for immediate or one-time tasks. Once the immediate operation is completed, the anonymous object becomes unreferenced.

public class Example{
    public static void main(String[] args) {
        // Create anonymous objects
        new MyClass(); // Object 1
        new MyClass(); // Object 2
        // Invoke garbage collection explicitly
        System.gc();
        // Perform some other operations  
        // ...
    }
}
class MyClass {
    // Class definition
}

In this example, two anonymous objects of MyClass are created. These objects are created without assigning them to any reference variables. They are simply instantiated and used within the same line of code.

Since no reference variables are pointing to these anonymous objects, they become eligible for garbage collection immediately after creation. They are considered unreachable, as there are no references to access them.

When garbage collection is triggered (either automatically or explicitly with System.gc()), it identifies that these anonymous objects are not reachable and reclaims their memory.

It's important to note that anonymous objects are typically limited to cases where the objects are used for a specific purpose within a single line of code and don't require further access or manipulation. In such cases, the objects can be created and discarded without explicit references.

Types of Activities in Java Garbage Collection

Managing and reclaiming occupied memory by unused objects is performed through garbage collection in Java. Java's garbage collector classifies this process into two categories:-

Minor or incremental garbage collection

Minor garbage collection, also known as incremental garbage collection, frees up memory in the young generation of the Java heap. The Java heap is divided into different generations: 

  • The young generation

  • The old generation 

  • The permanent generation or metaspace in Java 8+ 

Minor garbage collection is designed to be quick and efficient, targeting a small portion of the heap. Its purpose is to collect short-lived objects and release memory in the young generation, enabling the allocation of new objects without resorting to a full garbage collection.

Major or full garbage collection

Major garbage collection, or complete garbage collection, involves the collection of unused objects in the Java heap, encompassing both the young and old generations. Unlike minor garbage collection, major garbage collection is more time-consuming as it scans the entire heap and executes a more extensive process. 

During major garbage collection in Java, the garbage collector identifies and collects objects no longer reachable to the young and old generations. It temporarily pauses the application's execution in a "stop-the-world" scenario. 

Major garbage collection is typically triggered when certain conditions are met, such as when the young generation can no longer accommodate new objects or when the heap is nearly full. Its purpose is to collect long-lived objects and release memory occupied by no longer necessary objects.

Important Concepts Related to Garbage Collection in Java

Unreachable objects

A significant concept in Java's garbage collection is the notion of "unreachable objects." These objects are no longer accessible or referenced by any part of the program. Since they can't be used or accessed anymore, they become useless and occupy memory resources unnecessarily.

During the garbage collection process, Java's garbage collector detects and gathers these unreachable objects to free up the memory they occupy. This ensures effective management of memory and avoids memory leaks.

Eligibility for garbage collection

The term "eligibility for garbage collection in Javascript" pertains to the requirements that must be fulfilled for an object to be considered by the garbage collector for collection. When an object is unreachable, there are no references from any live objects or variables in the program.

Ways to make an object eligible for Garbage Collector

Some common ways to make an object eligible for garbage collection in Java are:

  • Nullifying the Reference:

  • Reassigning the Reference:

  • Exiting the Block or Method:

  • Objects in Java 8+ Lambdas:

  • Objects in Java 8+ Streams:

Ways for requesting JVM to run Garbage Collector

In Java, you can request the JVM to run the garbage collector using the System.gc() method or the Runtime.getRuntime().gc() method.

However, it's important to note that these methods are not guaranteed to perform immediate garbage collection. The JVM has the final authority on whether to run the garbage collector. Here are the ways to request the JVM to run the garbage collector:

Finalization

Finalization in Java's garbage collection refers to carrying out necessary cleanup tasks on objects on the verge of being garbage collected. It entails the execution of the finalize() method of an object before the garbage collector reclaims its memory. The finalize() method, a protected method in the Object class, can be overridden in a subclass to define customized cleanup operations.

When an object becomes eligible for garbage collection in Javascript, the JVM verifies whether it possesses a finalize() method. If the method is present, it is scheduled for execution before the object's memory is reclaimed. This allows the object to perform essential cleanup actions, such as closing open resources or releasing external references.

Here is an example:

Advantages of Garbage Collection in Java

Garbage collection in Java brings multiple benefits:-

  • Automated memory management: Manual memory allocation and deallocation are no longer necessary, reducing the chances of memory leaks and dangling pointers.

  • Increased efficiency: Developers can focus on application logic as garbage collection handles memory management, reducing memory-related bugs.

  • Enhanced program stability: Memory-related issues like segmentation faults and buffer overflows are minimized, leading to more reliable Java programs.

  • Optimal memory utilization: Unused memory is reclaimed by the garbage collector, optimizing memory usage and preventing fragmentation.

  • Dynamic memory allocation: Garbage collection enables flexible and scalable memory allocation, making Java programs more adaptable.

Real-World Example

Here is a real-world example of garbage collection in a Java program:

Concluion

Java garbage collection is a valuable aspect that automates memory management and brings a host of benefits to developers. It optimizes memory utilization, mitigates memory leaks, and allows for dynamic memory allocation, resulting in more efficient and scalable Java applications.

With garbage collection in Java for memory management, developers can concentrate on constructing robust and efficient software solutions. To take a further step into Java, consider enrolling yourself in the numerous professional computer science programs upGrad offers.

FAQs

1. Can garbage collection have an impact on performance?

Garbage collection can briefly pause the execution of the application, referred to as "stop-the-world" pauses. At the same time, it scans and collects unreachable objects and may have a minimal effect on applications requiring real-time or low latency.

2. Is it possible to control when garbage collection occurs in Java?

In general, explicitly requesting garbage collection is not advisable since the JVM handles it automatically. However, you can suggest the JVM initiate garbage collection using the System. gc() method. 

3. How can one streamline garbage collection in Java?

In Java, the garbage collection parameters like heap size, generation sizes, and collection algorithms can be fine-tuned, making it easy to optimize garbage collection performance. These methods rely on specific memory requirements and usage patterns of the application. 

Leave a Reply

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