Mastering Java Garbage Collection: From JVM Memory Layout to GC Tuning
This comprehensive guide explains the JVM memory areas, the fundamentals of garbage collection, generational heap management, various GC algorithms, and practical tuning parameters for Java applications.
As a Java developer, understanding the JVM's garbage collection (GC) mechanism is essential. This article shares personal insights and experiences on GC, covering the JVM runtime data areas, GC basics, generational memory management, collector types, and tuning options.
JVM Runtime Data Areas
The JVM memory is divided into five main regions:
Method Area : Stores class metadata, including class names, types, fields, and methods.
Heap : Holds all object instances created by new, this, and arrays. It is managed by the GC.
Stack : Each thread has its own stack storing method call frames, local variables, and return addresses. Stack frames are pushed and popped in a LIFO manner.
PC Register : Holds the address of the current executing instruction for each thread.
Native Method Stack : Executes native code (e.g., C/C++) separate from the Java stack.
Basic GC Concepts
GC automatically reclaims memory occupied by unreachable objects in the heap. The process can be visualized as a mother cleaning a messy room: objects are marked as garbage, then removed, and finally the remaining live objects are compacted to eliminate fragmentation.
Marking : Scan all heap objects and label reachable ones.
Normal Deletion : Remove objects that were marked as unreachable.
Deletion with Compacting : After removal, shift surviving objects to make memory contiguous.
GC roots (e.g., stack references, static fields, JNI references) serve as starting points for reachability analysis. Objects not reachable from any root are eligible for collection.
Generational GC
Because most objects die young, the heap is split into three generations:
Young Generation (Eden + two Survivor spaces S0/S1): New objects are allocated here. When Eden fills, a minor GC occurs, moving surviving objects to a Survivor space. After several minor GCs (controlled by MaxTenuringThreshold), objects are promoted to the Old Generation.
Old Generation (Tenured): Holds long‑lived objects. When it fills, a major or full GC is triggered.
Permanent Generation (MetaSpace in newer JDKs): Stores class metadata; its impact on GC is minimal.
The Young Generation typically uses a copying collector (mark‑copy), while the Old Generation historically used mark‑sweep or mark‑compact algorithms.
GC Algorithms and Collectors
Four main collectors are available in HotSpot:
Serial : Single‑threaded, uses mark‑copy for young and mark‑compact for old. Simple but can cause long stop‑the‑world pauses.
Parallel : Multi‑threaded, focuses on throughput. Uses parallel mark‑copy for young and parallel mark‑compact for old. Suitable for CPU‑bound workloads where pause time is less critical.
CMS (Concurrent Mark‑Sweep) : Aims to minimize pause times. Performs most work concurrently, using parallel mark‑sweep for the old generation and a parallel young collector. Good for latency‑sensitive services.
G1 (Garbage‑First) : Divides the heap into many equal‑sized regions (up to 2000). Uses a mix of young and mixed (young + selected old) collections, employing concurrent marking and region‑based compaction. Designed for large heaps (>4 GB) with predictable pause times.
Common Tuning Parameters
-XX:+UseSerialGC // Use Serial collector for both generations
-XX:+UseParNewGC // Parallel collector for young generation
-XX:+UseParallelGC // Parallel collector for young generation (throughput‑oriented)
-XX:+UseParallelOldGC // Parallel collector for old generation
-XX:ParallelGCThreads=n // Number of GC threads
-XX:+UseConcMarkSweepGC // Enable CMS (young: parallel, old: concurrent mark‑sweep)
-XX:+UseG1GC // Enable G1 collector
-XX:MaxTenuringThreshold=n // Age threshold for promotion to old generation (default 15)Choosing and Optimizing a Collector
When evaluating a collector, consider:
Throughput (overall work done vs. GC time)
GC overhead (CPU cost)
Pause duration
GC frequency
Heap size requirements
Object lifetimes
For high‑throughput batch jobs, Parallel is often best. For low‑latency services, CMS or G1 provide shorter pauses. G1 is especially effective for large heaps because it compacts regions incrementally, reducing fragmentation.
Further Reading
The article references a detailed case study from Meituan‑Dianping on Java GC optimization, which discusses frequent minor GCs, CMS performance spikes, and stop‑the‑world pauses, offering practical tips when code‑level changes are limited.
Overall, mastering JVM memory layout, understanding each collector’s algorithm, and applying appropriate tuning flags enable developers to achieve stable performance and avoid GC‑related bottlenecks.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Senior Brother's Insights
A public account focused on workplace, career growth, team management, and self-improvement. The author is the writer of books including 'SpringBoot Technology Insider' and 'Drools 8 Rule Engine: Core Technology and Practice'.
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.
