Working with Garbage Collection

1. Understanding GC Types

GCBest For
SerialTiny heaps, single CPU
ParallelThroughput-oriented batch
G1 (default)Balanced, < 200 ms pauses
ZGCSub-ms pauses, TB heaps
ShenandoahLow-pause concurrent
EpsilonNo-op (testing)

2. Using G1 Garbage Collector

AspectDetail
Default sinceJava 9
Region-basedHeap split into ~2048 regions
Goal-XX:MaxGCPauseMillis=200
Mixed collectionsYoung + selected old regions

3. Using Low-Latency GCs

GCPauseNotes
ZGC< 1 msGenerational since Java 21
Shenandoah~1–10 msConcurrent compaction
Trade-off~5–15% throughput cost

4. Configuring GC Flags (-XX:+UseG1GC, -XX:+UseZGC)

FlagUse
-XX:+UseG1GCDefault since JDK 9
-XX:+UseZGC -XX:+ZGenerationalGenerational ZGC (Java 21+)
-XX:+UseShenandoahGCShenandoah
-XX:+UseParallelGCThroughput
-XX:+UseSerialGCTiny heaps

5. Understanding GC Phases

PhaseDetail
MarkingIdentify live objects from roots
SweepingReclaim dead
CompactionReduce fragmentation
Concurrent vs STWModern GCs do most work concurrently

6. Understanding Stop-The-World Events

CauseDetail
SafepointAll app threads paused
Initial mark / RemarkG1 STW phases
Class redefinitionJVMTI agent action
Bias revocation(removed in Java 15+)

7. Monitoring GC Activity

ToolUse
-Xlog:gc*Unified logging (Java 9+)
jstat -gcutil% utilization
JFRRecording-based
GCViewer / GCEasyLog analyzers

8. Tuning GC Parameters

FlagEffect
-XX:MaxGCPauseMillis=NG1 pause goal
-XX:G1HeapRegionSize=NRegion size (1–32 MB)
-XX:InitiatingHeapOccupancyPercent=NConcurrent cycle trigger
-XX:ParallelGCThreads / ConcGCThreadsWorker counts

9. Understanding Finalization

Warning: Object.finalize() is deprecated since Java 9 and slated for removal. It is unreliable, slow, and can resurrect objects. Use Cleaner or try-with-resources instead.
StatusJava Version
Deprecated9
Default disabledJava 18 (--finalization=disabled)
Removal plannedFuture LTS

10. Using Cleaner API

Example: Cleaner

private static final Cleaner CLEANER = Cleaner.create();
public class Resource implements AutoCloseable {
    private final Cleaner.Cleanable cleanable;
    public Resource() {
        cleanable = CLEANER.register(this, () -> release(/* state */));
    }
    public void close() { cleanable.clean(); }
    private static void release(Object state) { /* free native */ }
}
AspectDetail
ActionMust NOT reference owner — use static state holder
ThreadRuns on cleaner-owned daemon thread

11. Understanding Reference Types

TypeGC Behavior
StrongNever collected while reachable
SoftCollected before OOM (memory-sensitive cache)
WeakCollected at next GC
PhantomEnqueued post-finalization; safer than finalize

12. Using Reference Queues

Example: Phantom + queue

ReferenceQueue<Object> q = new ReferenceQueue<>();
PhantomReference<Object> ref = new PhantomReference<>(target, q);
// background thread:
while (true) { Reference<?> r = q.remove(); cleanup(r); }
APIUse
queue.poll() / remove()Drain enqueued refs
Use caseDeterministic cleanup of off-heap resources