What is Garbage Collection
Garbage Collection (GC) is the process by which the JVM automatically frees up memory by removing objects that are no longer reachable in the program. It runs in the background along with the Java application, reclaiming unused memory to improve performance and avoid memory leaks.
🔹Purpose of Garbage Collection in Java
In Java, garbage collection (GC) is the process of automatically reclaiming memory by removing objects that are no longer reachable or needed by the application.
- Java programs create many objects dynamically (using
new). - Some of these objects may only be used temporarily. Once no references point to them, they become eligible for garbage collection.
- Instead of requiring developers to explicitly free memory (like in C/C++ with
free()ordelete), Java’s GC automates memory cleanup.
🔹Automated Nature of Garbage Collection
- No manual deallocation: Developers don’t have to explicitly release memory. The Java Virtual Machine (JVM) handles it.
- Background process: The GC runs in the background, periodically scanning the heap to find unused objects.
- Reachability analysis: GC uses a graph of object references starting from “roots” (like local variables, static fields, and active threads). If an object cannot be reached from any root, it is considered garbage.
- Algorithms: The JVM uses different GC algorithms (e.g., Mark-and-Sweep, G1, ZGC) depending on performance requirements.
🔹Why Memory Management Matters
Even though Java has automatic GC, memory issues can still occur if resources are not handled correctly:
- Avoiding
OutOfMemoryError- If the heap fills up with objects that are still referenced (or not collected quickly enough), the JVM can throw an
OutOfMemoryError. - Example: Loading millions of large objects without proper disposal can exhaust heap space.
- If the heap fills up with objects that are still referenced (or not collected quickly enough), the JVM can throw an
- Preventing Memory Leaks
- A memory leak happens when objects are no longer needed but still kept referenced (e.g., in collections like
ListorMap). - GC cannot collect these objects, leading to gradual memory exhaustion.
- Example: Forgetting to remove old listeners, cache entries, or closing database connections.
- A memory leak happens when objects are no longer needed but still kept referenced (e.g., in collections like
- Application Performance
- Efficient memory management ensures fewer GC pauses, smoother performance, and better scalability.
- Poor management → frequent GC cycles, longer pauses, sluggish application behavior.
📝 In short:
Garbage collection in Java automates memory cleanup, reducing developer burden and errors. Still, developers must write mindful code to avoid memory leaks and manage resources properly, or they risk OutOfMemoryError and performance issues.
🔹 JVM Memory Architecture Overview
When a Java program runs, the JVM divides memory into different runtime areas. These ensure that objects, variables, and methods are managed efficiently.
1. Heap Memory
Heap is the runtime area where all objects are stored. It is shared among all threads.It is further divided into generations to optimize garbage collection:
- Young Generation
- Where new objects are created.
- Further divided into:
- Eden Space → New objects are allocated here first.
- Survivor Spaces (S0, S1) → Objects that survive garbage collection in Eden are moved here.
- Frequent garbage collections happen here (Minor GC).
- Old Generation (Tenured)
- Stores long-lived objects that survived multiple GC cycles.
- Garbage collection here is less frequent but more expensive (Major GC / Full GC).
- Metaspace (Java 8+)
- Replaced PermGen.
- Stores class metadata (class definitions, method info, static variables).
- Grows dynamically, unlike the fixed-size PermGen.
2. Stack Memory
- Each thread has its own stack.
- Stores:
- Method call frames.
- Local variables (including primitives).
- References to objects (but not the objects themselves).
- When a method is invoked, a new frame is pushed; when the method ends, the frame is popped.
If stack space runs out (e.g., due to deep recursion), a StackOverflowError occurs.
3. Other Areas (briefly)
- Program Counter (PC) Register: Holds the address of the currently executing instruction for each thread.
- Native Method Stack: Supports execution of native (non-Java) code.
🔹 JVM Memory Structure Diagram
+-------------------------+
| JVM Memory |
+-------------------------+
+-------------------------+
| Heap Memory | (Shared across threads)
|-------------------------|
| Young Generation |
| - Eden Space |
| - Survivor 0 (S0) |
| - Survivor 1 (S1) |
|-------------------------|
| Old Generation |
|-------------------------|
| Metaspace (Java 8+) |
+-------------------------+
+-------------------------+
| Stack Memory | (Per thread)
| - Method frames |
| - Local variables |
| - References |
+-------------------------+
+-------------------------+
| PC Register (per thread)|
+-------------------------+
| Native Method Stack |
+-------------------------+
📝 In short:
- Heap → Objects (Young: Eden + Survivor, Old, Metaspace).
- Stack → Method calls, primitives, object references (thread-local).
- Other parts like PC Register and Native Stack support execution.
🔹Ways to Make an Object Eligible for Garbage Collection :
- Nullifying the reference variable
- Reassign the reference variable
- Objects created inside a metho
✅1. Nullifying the reference variable
If an object is no longer required, you can make it eligible for GC by assigning null to its reference variable:
Student s1 = new Student();
s1 = null; // Now eligible for GC

✅2.Reassigning the reference variable
If a reference variable is reassigned to point to another object, the old object becomes unreachable and eligible for Garbage Collection(GC).
Student s1 = new Student();
Student s2 = new Student();
s1 = s2; // Old s1 object is now eligible for GC

✅3.Objects created inside a method
Objects created inside a method are eligible for Garbage Collection (GC) once the method completes, provided there are no references to them outside the method:
void myMethod() {
MyClass obj = new MyClass();
// obj is eligible for GC after method execution
}
Example:
class MyClass {
int id;
MyClass(int id) {
this.id = id;
System.out.println("Object " + id + " created");
}
// finalize() is deprecated after Java 9,
// but here we use it only for demonstration
@Override
protected void finalize() throws Throwable {
System.out.println("Object " + id + " is garbage collected");
}
}
public class GCDemo {
public static void main(String[] args) {
createObject();
// Requesting JVM to run GC
System.gc();
// Adding delay to give GC some time
try { Thread.sleep(1000); } catch (InterruptedException e) {}
System.out.println("End of main method");
}
static void createObject() {
MyClass obj = new MyClass(1);
// After this method ends, 'obj' goes out of scope
// and becomes eligible for Garbage Collection
}
}
Explanation
- Inside
createObject()objis a local variable referring to aMyClassobject.- When the method finishes, the variable
objgoes out of scope.
- After method execution
- No references to that object remain.
- Hence, the object becomes eligible for Garbage Collection.
System.gc()call- Requests JVM to run the GC.
- If the JVM runs GC, the overridden
finalize()method is called, and you’ll see:
Object 1 is garbage collected
✅Ways for Requesting the JVM to Run Garbage Collector
Although you cannot force garbage collection, you can request it using the folowing methods:
✅System.gc()
A static method in the System class that requests GC.
System.gc()
System.gc() method is used to call the garbage collector to perform clean-up processing.
✅Runtime.getRuntime().gc()
The Runtime class, present in the java.lang package, is a singleton that provides the gc() method through the getRuntime() factory method.
Runtime.getRuntime().gc();
👉 Both methods are (System.gc() and Runtime.getRuntime().gc() )equivalent, but the JVM is not obligated to perform garbage collection immediately.
Quest : Can Garbage Collection be forced?
❌ No. Garbage Collection cannot be forced. You can only request it, but the JVM decides when (or if) it will actually run.
✅Finalization (⚠️ Deprecated)
Before destroying an object, the Garbage Collector (GC) once invoked the finalize() method to perform cleanup activities.
@Override
protected void finalize() throws Throwable {
// cleanup code
}
- The
finalize()method is defined in theObjectclass:
⚠️ Note: Since Java 9, the finalize() method has been deprecated and its use is strongly discouraged. Developers should instead use alternatives such as try-with-resources or implement the AutoCloseable interface for cleanup tasks.
try-with-resourcesfor automatic resource management, orAutoCloseableinterface for cleanup tasks.
✅Memory Leak
A memory leak occurs when an object is no longer needed by the application but is still being referenced. This prevents GC from reclaiming it, leading to unnecessary memory consumption.
This results in unnecessary memory consumption and may cause the application to slow down or even crash.
✅Common Causes of OutOfMemoryError(OOM) in JVM
When the JVM runs out of memory and cannot allocate more objects or native resources, it throws an OutOfMemoryError. This can happen in several scenarios depending on how the application uses memory.
- Java Heap Space Exhaustion
- GC Overhead Limit Exceeded
- Metaspace Exhaustion (Java 8 and later)
- Native Memory Exhaustion
- Array Size Limit Exceeded
- Kernel or OS Memory Limits
👉 To learn more about the different types of OutOfMemoryError and how to fix them, check out our detailed guide on OutOfMemoryError in Java.

One comment on “Complete Guide to Garbage Collection in Java”