Mastering Java GC: Deep Dive into JVM Memory and Garbage Collection
This article explains the JVM runtime memory areas, the fundamentals of garbage collection, generational heap organization, and the characteristics of major GC collectors, providing practical insights and optimization tips for Java developers seeking to understand and improve JVM performance.
Preface
As an ambitious Java programmer, mastering the mechanisms of garbage collection (GC) is essential. This article shares personal insights and experiences on learning GC.
JVM Runtime Data Areas
The JVM runtime memory consists of five main parts:
Method Area
Stores class metadata such as class names, types, fields, and methods.
Heap
Each JVM instance has a single heap that holds objects created with new, this, and arrays, managed by the garbage collector.
Stack
Each thread has its own stack storing method call frames, local variables, and temporary data in a LIFO order.
PC Register
Each thread has a program counter register that holds the address of the next instruction.
Native Method Stack
Used for executing native code (e.g., C/C++) separate from the Java stack.
Getting Started with GC
GC automatically finds and reclaims unused objects in the heap, similar to a mother cleaning a messy room.
Marking
The collector scans all objects, marking those that are unreachable.
Normal Deletion
Marked objects are removed from memory.
Deletion with Compacting
After removal, live objects are moved to eliminate fragmentation and create contiguous free space.
Java uses a root-search algorithm (GC Roots) to identify reachable objects. Objects reachable from GC Roots are considered live; others can be reclaimed.
GC Roots include:
Objects referenced from the Java stack
Static fields in the method area
Constants in the method area
Objects referenced by native methods in the native stack
Since JDK 1.2, references are classified as strong, soft, weak, and phantom, with decreasing strength.
Generations and GC Mechanisms
The heap is divided into three generations: Young, Old, and Permanent.
Young Generation
New objects are allocated in the Eden space; two Survivor spaces (S0 and S1) hold objects that survive minor GC cycles. When Eden fills, a Minor GC occurs, moving surviving objects to a Survivor space and discarding unreachable ones.
Objects that survive a configurable number of Minor GCs are promoted to the Old Generation.
The Young Generation uses a copying algorithm (Copying GC) that copies live objects from a From space to a To space, then swaps the roles of the spaces.
void copying() {
$free = $to_start; // $free is the offset in the To space
for (r : $roots)
*r = copy(*r); // copy and update reference
swap($from_start, $to_start); // exchange From and To after GC
}Old Generation
Stores long-lived objects. Major GC (Full GC) reclaims space in the Old Generation and can be a stop‑the‑world event.
Initially, the Old Generation used a mark‑sweep algorithm, which can cause fragmentation. Modern JVMs use a mark‑compact algorithm to reduce fragmentation.
Permanent Generation
Part of the Method Area, it holds metadata such as class definitions. It has little impact on GC, though newer JVMs can reclaim unused classes and constants.
GC Collectors and Optimization
When evaluating GC collectors, consider throughput, overhead, pause time, frequency, heap size, and object lifetimes. The main collectors are:
Serial – single‑threaded, uses mark‑copy; invoked with -XX:+UseSerialGC.
Parallel – multi‑threaded, focuses on throughput; enabled with -XX:+UseParallelGC and -XX:+UseParallelOldGC.
CMS (Concurrent Mark‑Sweep) – aims for low pause times; enabled with -XX:+UseConcMarkSweepGC.
G1 (Garbage‑First) – reduces Full GC frequency, uses mark‑compact; enabled with -XX:+UseG1GC. G1 divides the heap into many equal‑sized regions and includes a Humongous region for very large objects.
Common JVM options:
-XX:+UseSerialGC // Serial collector for both generations
-XX:+UseParNewGC // Parallel collector for young generation
-XX:+UseParallelGC // Parallel collector focusing on throughput
-XX:+UseParallelOldGC // Parallel collector for old generation
-XX:ParallelGCThreads=n // Number of GC threads
-XX:+UseConcMarkSweepGC // CMS collector
-XX:ParallelCMSThreads=n // CMS thread count
-XX:+UseG1GC // Enable G1 collectorIn summary, choose and tune the GC collector based on your application's performance requirements and workload characteristics.
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.
Java Interview Crash Guide
Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.
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.
