Unravel โบ Java concepts โบ JVM and performance
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
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.
- 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.
- 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)
- 3Collectors: G1 (default, balanced), ZGC and Shenandoah (very short pauses on big heaps), Parallel (throughput), Serial (tiny programs)Choose with -XX:+UseG1GC, -XX:+UseZGC, ...
- 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
- System.gc() is only a hint and can trigger a full, slow collection; remove it from production code (or disable with -XX:+DisableExplicitGC)
- GC pauses show up as latency spikes
- G1 divides the heap into regions and collects the ones with most garbage first, with concurrent marking to find live objects
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"); }}- line 4 uses GarbageCollectorMXBean, the core of Garbage collection
- line 5 uses gc, the core of Garbage collection
- 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
finalizeto 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:
- Types:
CleanerReferenceQueueGarbageCollectorMXBeanPhantomReference - Method calls:
System.gc()Runtime.gc()getGarbageCollectorMXBeans() - Method names you declare:
finalize() - Configuration keys:
-XX:+Useโฆ-Xlog:gcโฆ
Part of a learning path
- The JVM and the environment ยท previous: JVM memory: heap, stack and limits ยท next: Weak and soft references
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.