0
0
JavaHow-ToBeginner · 4 min read

How Garbage Collector Works in Java: Simple Explanation and Example

In Java, the Garbage Collector automatically frees memory by removing objects that are no longer reachable in the program. It runs in the background and helps manage memory without manual intervention, preventing memory leaks and improving performance.
📐

Syntax

Java's garbage collection is automatic and does not require explicit syntax to invoke. However, you can suggest garbage collection using System.gc(), but it is only a request, not a command.

  • System.gc(): Suggests the JVM to run garbage collection.
  • finalize(): A method that can be overridden to clean up before an object is collected (deprecated in newer Java versions).
java
public class GarbageCollectorDemo {
    public static void main(String[] args) {
        MyObject obj = new MyObject();
        obj = null; // Object is now eligible for garbage collection
        System.gc(); // Suggest garbage collection
    }
}

class MyObject {
    @Override
    protected void finalize() throws Throwable {
        System.out.println("Garbage collector called for MyObject");
        super.finalize();
    }
}
💻

Example

This example shows how an object becomes eligible for garbage collection when no references point to it. The System.gc() call suggests the JVM to run garbage collection, which may call the finalize() method before reclaiming memory.

java
public class GarbageCollectorExample {
    public static void main(String[] args) {
        GarbageCollectorExample obj1 = new GarbageCollectorExample();
        GarbageCollectorExample obj2 = new GarbageCollectorExample();

        obj1 = null; // obj1 is now eligible for garbage collection

        System.gc(); // Suggest garbage collection

        System.out.println("End of main method");
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("Garbage collector called for object");
        super.finalize();
    }
}
Output
Garbage collector called for object End of main method
⚠️

Common Pitfalls

1. Relying on System.gc() to force garbage collection: This is only a suggestion to the JVM and does not guarantee immediate collection.

2. Overusing finalize() method: It is deprecated and can cause performance issues; use try-with-resources or Cleaner API instead.

3. Memory leaks due to lingering references: Objects are not collected if references still exist, even if unused.

java
public class MemoryLeakExample {
    static class Container {
        Object[] data = new Object[1000000];
    }

    public static void main(String[] args) {
        Container container = new Container();
        // Even if we don't use container, it still holds large data
        // Setting container to null allows GC to reclaim memory
        container = null;
        System.gc();
        System.out.println("Memory leak avoided by nullifying reference");
    }
}
Output
Memory leak avoided by nullifying reference
📊

Quick Reference

  • Garbage Collector: Automatically frees memory of unreachable objects.
  • System.gc(): Suggests JVM to run GC, not guaranteed.
  • finalize(): Deprecated cleanup method before object removal.
  • Memory leaks: Caused by lingering references preventing GC.
  • Best practice: Let JVM manage memory; avoid forcing GC.

Key Takeaways

Java's garbage collector automatically frees memory by removing unreachable objects.
You can suggest garbage collection with System.gc(), but it is not guaranteed to run immediately.
Avoid relying on finalize() as it is deprecated and can cause performance issues.
Memory leaks happen when references to unused objects are still held, preventing garbage collection.
Let the JVM manage memory automatically and avoid forcing garbage collection in normal code.