Mastering JVM Memory: Models, GC Algorithms, and Optimization Tips
This article provides a comprehensive overview of the JVM memory model, garbage collection algorithms, various collectors and their trade‑offs, class loading steps, object lifecycle, escape analysis, and practical tuning commands for optimizing Java applications.
1. JVM Memory Model
The JVM loads classes through a subsystem that performs verification, preparation, resolution, and initialization. Method calls push frames onto the stack, objects reside in the heap, and references in the stack point to them. The metaspace holds static methods and does not consume the JVM's native heap.
2. JVM Garbage Collection Algorithms
Copying algorithm : copies live objects from one memory region to another, requiring half of the heap as a spare space.
Mark‑Sweep : marks reachable objects and sweeps away the rest, which can lead to memory fragmentation.
Mark‑Compact : an improvement over Mark‑Sweep that eliminates fragmentation by moving live objects together, but it must update references during the compaction phase.
3. JVM Garbage Collectors and Their Pros/Cons
There are five main collectors:
Serial : single‑threaded, simple but offers limited performance benefits.
ParNew : parallel young‑generation collector; works well when thread count matches CPU cores but is not ideal for the old generation.
Parallel Scavenge : high‑CPU parallel collector that may compete with application threads for CPU resources.
CMS (Concurrent Mark‑Sweep) : aims to minimize pause times; phases include Initial Mark (STW), Concurrent Mark, Remark (STW, ~70% of pause), Concurrent Sweep, and Concurrent Reset. It requires an old‑generation guarantee mechanism.
G1 (Garbage‑First) : suited for large‑heap servers; phases are Initial Mark (STW), Concurrent Mark, Final Mark (STW), and Evacuation Pause (STW). G1 can control STW duration.
G1 also defines three GC types: Young GC (triggered when Eden is full), Mixed GC (cleans selected regions and may perform a full GC), and Full GC (stops all application threads).
4. Class Loading Process
The loading lifecycle consists of five steps:
Verification : checks the correctness of the bytecode.
Preparation : allocates memory for static fields and assigns default values.
Resolution : replaces symbolic references with direct references (static linking).
Initialization : assigns values to static fields and executes static blocks.
Usage (and eventual Unloading ).
Parent‑Delegation Model
Class loading follows a delegation hierarchy: custom class loader → application class loader → extension class loader → bootstrap class loader. If a loader cannot find a class, it delegates to the next level, eventually falling back to the bootstrap loader.
5. Old‑Generation Guarantee Mechanism
When Eden fills, the JVM first checks whether the old generation has enough free space for the objects to be promoted. If not, it may trigger a Full GC. The behavior depends on the flag -XX:-HandlePromotionFailure (enabled by default in JDK 8) and on the average size of objects promoted after each Minor GC.
6. Java Object Creation Process
The steps are:
Allocate memory for the object.
Begin constructor execution.
Recursively invoke super‑class constructors.
Initialize instance fields.
Execute the constructor body.
After use, the object becomes a GC root candidate, may run finalize(), and is eventually reclaimed.
7. Class Lifecycle Summary
Load → Verify → Prepare → Resolve → Initialize → Use → Unload.
8. Determining When an Object Can Be Collected
Reference‑counting (rarely used due to inability to handle cycles).
Reachability analysis: objects reachable from GC roots (thread stacks, static fields, JNI handles) are alive.
Reference types: strong, soft, weak, phantom.
Finalization: finalize() can delay reclamation.
9. When Minor GC and Full GC Occur
Minor GC is triggered when the young generation’s Eden space becomes full. Full GC runs in the old generation, often caused by the old‑generation guarantee mechanism after a Minor GC.
10. Dynamic Age Determination for Objects
After a Minor GC, surviving objects are placed in the Survivor “to” space. Their ages are summed; when the total size reaches the capacity of the “to” space, all objects of that age and older are promoted to the old generation (typically when they occupy more than 50 % of Survivor).
11. Class Instantiation Order
When a class instance is created, the order is:
Static variables and static blocks (executed once per class).
Instance variables and instance initializer blocks.
Constructor body.
12. Escape Analysis
Enabled with -XX:+DoEscapeAnalysis (default since JDK 7) and disabled with -XX:-DoEscapeAnalysis. Escape analysis determines whether an object can be allocated on the stack instead of the heap, reducing GC pressure.
13. Common JVM Tuning Commands
-Xss: sets thread stack size (e.g., -Xss512K). -XX:MetaspaceSize / -XX:MaxMetaspaceSize: configure metaspace size. -Xms / -Xmx: set initial and maximum heap size. -Xmn / -XX:NewSize: configure young generation size. -XX:PretenureSizeThreshold: threshold for allocating large objects directly in the old generation. -XX:MaxTenuringThreshold: maximum age before promotion. -XX:-HandlePromotionFailure: enables old‑generation guarantee (default on JDK 8). -XX:-UseAdaptiveSizePolicy: disables automatic adjustment of Eden/Survivor ratios. -XX:SurvivorRatio: sets the ratio between Eden and Survivor spaces. -XX:NewRatio: sets the ratio between old and young generations.
These flags allow fine‑grained control over memory allocation and garbage‑collection behavior, helping to reduce pause times and improve overall performance.
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.
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.
