BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ JVM and performance

Java language

Garbage collection

The garbage collector frees objects that nothing can reach any more, so Java code never frees memory by hand.

Learn these first

At a glance

Mental model

A cleaning crew that walks through the warehouse starting from the doors (GC roots): everything it can reach by following references is kept, and everything else is thrown away.

What happens, in order
  1. 1An object is garbage when no chain of references leads to it from a root (local variables, static fields, active threads)Cycles do not keep each other alive.
  2. 2Generational collectors: most objects die young, so a young-generation collection is quick; survivors move to the old generation, which is collected less often (more costly)
  3. 3Collectors: G1 (default, balanced), ZGC and Shenandoah (very short pauses on big heaps), Parallel (throughput), Serial (tiny programs)Choose with -XX:+UseG1GC, -XX:+UseZGC, ...
  4. 4Look at GC with -Xlog:gc* (or -verbose:gc) and tools such as JFR, VisualVM and GC log viewers: watch pause times, how much is freed, and how fast the old generation fills
Remember
Watch out
Calling System.gc() to "fix" memoryRelying on finalize to release resourcesTuning flags before measuringKeeping references in static or long-lived collections
Example (highlighted lines explain it)
import java.lang.management.*;public class GcInfo {  static void report() {    for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans())      System.out.println(gc.getName() + " runs=" + gc.getCollectionCount() + " time=" + gc.getCollectionTime() + "ms");  }  static void bad() { System.gc(); }  @Override protected void finalize() { System.out.println("gone"); }}
  1. line 4 uses GarbageCollectorMXBean, the core of Garbage collection
  2. line 5 uses gc, the core of Garbage collection
  3. line 7 uses gc, the core of Garbage collection
Read the full explanation (about 2 min)

The garbage collector frees objects that nothing can reach any more, so Java code never frees memory by hand. You influence it with object lifetimes and heap settings, not by calling it.

A mental model

A cleaning crew that walks through the warehouse starting from the doors (GC roots): everything it can reach by following references is kept, and everything else is thrown away.

How it works

An object is garbage when no chain of references leads to it from a root (local variables, static fields, active threads). Cycles do not keep each other alive.

Generational collectors: most objects die young, so a young-generation collection is quick; survivors move to the old generation, which is collected less often (more costly).

Collectors: G1 (default, balanced), ZGC and Shenandoah (very short pauses on big heaps), Parallel (throughput), Serial (tiny programs). Choose with -XX:+UseG1GC, -XX:+UseZGC, ...

Look at GC with -Xlog:gc* (or -verbose:gc) and tools such as JFR, VisualVM and GC log viewers: watch pause times, how much is freed, and how fast the old generation fills.

Going deeper

System.gc() is only a hint and can trigger a full, slow collection; remove it from production code (or disable with -XX:+DisableExplicitGC). finalize() is deprecated: it delays reclaim and runs unpredictably. Use try-with-resources, or Cleaner as a safety net.

GC pauses show up as latency spikes. Reduce allocation rates in hot paths (avoid boxing, reuse buffers, avoid huge temporary collections) before tuning flags.

A growing old generation that never shrinks after full collections is the signature of a memory leak.

Under the hood

G1 divides the heap into regions and collects the ones with most garbage first, with concurrent marking to find live objects. Barriers on reference writes record cross-region references in remembered sets so a young collection does not scan the whole heap.

Common mistakes

  • Calling System.gc() to "fix" memory.
  • Relying on finalize to release resources.
  • Tuning flags before measuring.
  • Keeping references in static or long-lived collections.

How Unravel recognises it

When you paste code, Unravel looks for these signs of garbage collection. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Garbage collection?

The garbage collector frees objects that nothing can reach any more, so Java code never frees memory by hand. You influence it with object lifetimes and heap settings, not by calling it.

What are the most common mistakes with Garbage collection?

Calling System.gc() to "fix" memory. Relying on finalize to release resources. Tuning flags before measuring. Keeping references in static or long-lived collections.

How can I see Garbage collection in real code?

Paste your own Java into Unravel and it will point out where garbage collection appears, explain how it works at the detail level you choose, and draw the flow of the code around it.