Major GC Algorithms
Posted on March 14, 2024 • 5 minutes • 916 words • Other languages: Korean
Table of contents
This article was written with the intention of studying major GC algorithms more deeply while participating in the ‘Optimizing Java’ study.
Serial GC
- The simplest GC implementation
- Only one thread performs GC after Stop-The-World (STW)
- Uses the mark-sweep-compact algorithm
- Not suitable for multi-threaded environments
❖ Enable Serial GC flag
java -XX:+UseSerialGC
Parallel GC
- Default GC from Java 5 to 8
- Also known as the Throughput Collector as it maximizes GC throughput
- Advantageous algorithm when there is sufficient memory space and a high number of cores
- Flags can be used to configure parameters such as the maximum number of threads, maximum pause time, and GC execution time ratio
-XX:ParallelGCThreads=<N>
-XX:MaxGCPauseMillis=<N>
-XX:GCTimeRatio=<N>
❖ Enable Parallel GC flag
java -XX:+UseParallelGC
Parallel Old GC
- Old generation version of Parallel GC
- Performs GC in multiple threads up to the Old generation
- Uses the Mark-Summary-Compact algorithm for the Old generation
- Mark phase: Divides the Old generation into regions and marks frequently referenced objects in each region
- Summary phase: Determines the dense prefix among surviving objects, based on which the compact area is reduced
- Compact phase: Divides the compact area into destination and source, moves surviving objects to the destination, and removes unreferenced objects
❖ Enable Parallel Old GC flag
java -XX:+UseParallelOldGC
CMS GC
Concurrent Mark Sweep
❖ When prefixed with “Concurrent,” it means it is performed concurrently during application operation
- Initial Mark phase: Finds only live objects closest to the class loader and stops
- Concurrent Mark phase: Marks objects referenced by the confirmed live objects as roots
- Remark phase: Marks newly added or unlinked objects from the Concurrent Mark phase
- Concurrent Sweep phase: Removes unmarked objects
Advantages
- Very short STW time
- Also known as Low Latency GC
- Used when low response time is important
Disadvantages
- High CPU and memory usage
- No compaction phase, leading to potential memory fragmentation
- With a lot of fragmented memory, the STW time for compaction becomes much longer
❖ Enable CMS GC flag
java -XX:+UseConcMarkSweepGC
G1 GC
Garbage First
- Default GC from Java 9 onwards
- Completely different approach from previous GCs
- Used in multi-processor environments with ample memory space
- Manages memory by dividing the heap into regions called Region, each logically separated (Eden, Survivor, Old, Humongous, Available/Unused)
- Humongous: Area for storing large objects exceeding 50% of the region size
- Available/Unused: Area not yet used
GC Phases
- Global Marking phase: Determines the activity level of objects in each region
- Sweep phase: Collects garbage starting from almost empty regions to ensure significant free space
RSet (Remembered Set)
- Reference management device existing for each region to reference the inside of the heap from outside
- Used to track floating garbage
- floating garbage: Objects referenced by already dead objects, making them appear alive
Minor GC
- Performed when Eden space is full
- Moves surviving objects in Eden space to Survivor space
- Designates the now empty Eden space as Available/Unused
Major GC
- Initial Mark phase: Marks objects in the Survivor space referenced by objects in the Old generation (STW)
- Root Region Scan phase: Scans for Survivor objects found in the previous phase
- Concurrent Mark phase: Scans the entire heap → regions with no garbage are excluded from the next phase
- Remark phase: Identifies objects to be excluded from GC finally (STW)
- Cleanup phase: Removes unused objects from the region with the fewest live objects (STW)
- Copy phase: Performs compaction by moving surviving objects to new regions even after Cleanup (STW)
❖ Enable G1 GC flag
java -XX:+UseG1GC
Z GC
- Introduced as an experimental version in Java 11, officially released from Java 15 onwards
- STW time is below 10ms!
- Suitable for low-latency, concurrent, high-cost operations
- Handles heap sizes from 8MB to 16TB
- Like G1 GC, manages the heap by dividing it into regions, but each region has a different size
- Instead of regions, it distinguishes logical units called ZPage
- Consists of three types: small (2 MB), medium (32 MB), large (N * 2 MB)
Colored Pointers
- Utilizes 64-bit memory in pointers to store object state values
- Therefore, only usable on 64-bit operating systems!
- 42 bits are used for object addresses
- 4 bits represent the object’s state value
- Finalizable: Objects accessible only through finalizer (garbage)
- Remapped: Indicates whether the object is relocated
- Marked 1 / 0: Indicates accessible objects
- Executes mmap (multi-mapping) for all virtual addresses to save mapping operations between virtual and real addresses, leading to a threefold increase in memory usage
Load Barriers
- Code executed when referencing an object
- Checks whether the object in the heap is referenceable
- Executes a slow path process if there is a problem before referencing
- Provides a protective barrier before referencing objects
- Unlike G1 GC, prevents STW during memory reallocation process
- Updates references and marks while checking Remap Mark and Relocation Set
GC Phases
- Pause Mark Start phase: Marks objects pointed to from ZGC roots (Live Object)
- Each thread scans its local variables to create GC root sets (very short STW)
- Concurrent Mark/Remap phase: Marks all objects by exploring object references
- Performs coloring and remapping for objects accessible from GC roots
- Pause Mark End phase: Marks incoming objects
- Concurrent Prepare for Relocate phase: Finds areas for relocation and assigns them to the Relocation Set
- Relocation Set: Set of ZPages containing garbage
- Pause Relocate Start phase: Performs relocation and updates all root references
- Concurrent Relocate phase: Updates references after relocating all objects using Load Barriers
- Updates object addresses using forwarding tables
❖ Overwhelmingly low STW time with Z GC
❖ Enable Z GC flag
java -XX:+UseZGC
⚠️ For versions before Java 15, the -XX:+UnlockExperimentalVMOptions option must be added