Understanding Java Garbage Collection Algorithms and JVM GC Strategies
This article explains what constitutes garbage in the Java heap, compares reference‑counting and root‑reachability approaches, demonstrates a reference‑counting example, and reviews the main garbage‑collection algorithms and collectors (Serial, ParNew, Parallel Scavenge, Serial Old, Parallel Old, CMS, G1) used by modern JVMs.
Before discussing garbage collectors, the article introduces the concept of garbage in the Java heap and the criteria the JVM uses to identify objects that can be reclaimed.
What Is Garbage?
Garbage refers to heap objects that are no longer reachable; if an object can never be accessed again, it is considered collectible.
Reference Counting
Reference counting adds a counter to each object, incrementing on new references and decrementing when references disappear. An object with a zero count is eligible for collection, but this method cannot handle cyclic references and is not used by mainstream JVMs.
Code example:
package com.courage;
public class ReferenceCountingGC {
public Object instance = null;
private static final int _1MB = 1024 * 1024;
/**
* This field exists only to occupy memory so that GC logs can show whether it was reclaimed.
*/
private byte[] bigSize = new byte[5 * _1MB];
public static void testGC() {
//5 M
ReferenceCountingGC objA = new ReferenceCountingGC();
//5 M
ReferenceCountingGC objB = new ReferenceCountingGC();
objA.instance = objB;
objB.instance = objA;
objA = null;
objB = null;
// Assume GC occurs here; can objA and objB be reclaimed?
System.gc();
}
public static void main(String[] args) {
testGC();
}
}The execution log shows that after System.gc() the memory usage drops from 14 MB to 0 MB, confirming that the JVM does not rely on reference counting.
Root‑Reachability Algorithm
The algorithm starts from a set of GC Roots (e.g., thread stacks, static fields, JNI references, internal JVM references, synchronized locks, JMX beans) and traverses reference chains; objects not reachable from any root are deemed garbage.
Garbage‑Collection Algorithms
The article outlines three fundamental algorithms that underpin most JVM collectors: Mark‑Sweep, Mark‑Copy, and Mark‑Compact.
Mark‑Sweep
Marks reachable objects and then sweeps away unmarked ones. Drawbacks include unstable performance with many reclaimable objects and memory fragmentation.
Mark‑Copy
Divides the heap into two equal regions; live objects are copied to the other region when one fills up, eliminating fragmentation but halving usable memory.
Mark‑Compact
After marking, all live objects are moved to one end of the heap, and the remaining space is reclaimed, avoiding fragmentation at the cost of moving objects.
Garbage Collectors Derived from These Algorithms
Serial Collector
A single‑threaded collector that pauses all application threads during collection; suitable for client‑side JVMs with limited resources.
ParNew Collector
The multithreaded version of Serial, sharing the same parameters and algorithms; commonly used as the young‑generation collector in older server‑mode JVMs.
Parallel Scavenge Collector
A young‑generation collector based on Mark‑Copy that focuses on maximizing throughput rather than minimizing pause times.
Serial Old Collector
The old‑generation counterpart of Serial, using Mark‑Compact; serves as a fallback for CMS failures.
Parallel Old Collector
The old‑generation version of Parallel Scavenge, also using Mark‑Compact and supporting multithreaded collection.
CMS (Concurrent Mark‑Sweep) Collector
Targets low pause times by performing most of its work concurrently; it follows a four‑step cycle: initial mark, concurrent mark, remark, and concurrent sweep.
G1 (Garbage‑First) Collector
Introduces region‑based heap layout and mixed‑region collection, aiming for predictable pause times while maintaining high throughput; it treats the heap as a set of equal‑sized regions and collects those with the most garbage first.
Collector Summary
The typical combination of young‑generation and old‑generation collectors in modern JVMs is illustrated, showing how different collectors can be paired to balance throughput, pause time, and memory efficiency.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.