Java 11 introduced the Epsilon garbage collector, which is used in scenarios where no garbage collection is needed. It controls memory allocation but does not perform any garbage collection tasks. Once the heap memory is exhausted, the JVM shuts down directly. Additionally, ZGC (Z Garbage Collector) was introduced as an experimental garbage collector in Java 11, and Shenandoah GC was introduced in Java 12 as an experimental version, which became production-ready by Java 15. Java 17 marked the official LTS release with these enhancements.
1. What is ZGC?
ZGC (Z Garbage Collector) is a low-latency garbage collector in Java, specifically designed to handle large heap sizes, ranging from hundreds of MBs to 16 TB. It achieves this by using concurrent marking and concurrent relocation techniques to keep garbage collection pauses extremely low, typically under 1 millisecond, regardless of the heap size. ZGC incorporates several innovative technologies like colored pointers, load barriers, and memory multi-mapping to manage memory efficiently and perform garbage collection.
2. The Three-Color Marking Algorithm
The Three-Color Marking algorithm is used in garbage collection to track live objects in memory. It categorizes objects into three colors:
- White: The initial state, representing unvisited objects. These objects will be collected after marking is complete.
- Gray: Objects that have been visited but whose references have not yet been visited. Gray objects are in a transitional state during the marking process.
- Black: Objects that and all their referenced objects have been visited and marked as live.
3. ZGC Use Cases
ZGC is particularly useful in the following scenarios:
- Large Memory Applications: Such as real-time data analytics, high-performance servers, and online transaction systems, which need to handle TB-sized heap memory.
- Low Latency Requirements: Ideal for applications that require real-time responses, like high-frequency trading systems and online games. ZGC’s low pause times (typically less than 1ms) meet these needs.
- Cloud Computing Platforms: ZGC’s scalability and low-latency characteristics make it well-suited for managing shared resources in multi-tenant cloud environments.
4. How ZGC Works
ZGC’s garbage collection process includes several phases:
- Initial Mark: A quick marking phase where all the live roots are identified.
- Concurrent Marking: Concurrently marks live objects in the heap.
- Remark: Another short phase where the system reconciles any discrepancies.
- Concurrent Relocation: Moves the live objects and compacts the heap while the application continues to run.
5. ZGC's Current Challenges
Java has introduced a generational ZGC in recent updates. ZGC operates differently from traditional garbage collectors like CMS or G1 in that it does not have the concept of generations but uses regions similar to G1. ZGC's regions come in three sizes:
- Small Region: 2MB in size, holds objects smaller than 256KB.
- Medium Region: 32MB in size, for objects between 256KB and 4MB.
- Large Region: A flexible size (must be a multiple of 2MB), used for large objects (4MB+). These regions are not reallocated because copying large objects is very expensive.
6. ZGC's Pause Time Characteristics
Unlike CMS, where the entire garbage collection phase is Stop-The-World (STW), ZGC is designed to be almost entirely concurrent. ZGC has three STW phases: Initial Mark, Remark, and Initial Relocation. Most of the work is done concurrently, and pauses are not dependent on the heap size or the number of active objects. This ensures that ZGC achieves its goal of minimizing pauses.
7. ZGC Configuration Options
- -Xms -Xmx: Set both the minimum and maximum heap sizes to 10GB.
- -XX:ReservedCodeCacheSize: Set the size of the code cache used for JIT-compiled code.
- -XX:+UnlockExperimentalVMOptions -XX:+UseZGC: Enables ZGC in the JVM.
- -XX:ConcGCThreads: Specifies the number of threads for concurrent garbage collection. By default, it's 12.5% of the number of CPU cores.
- -XX:ParallelGCThreads: Defines the number of threads for STW phases. Default is 60% of the CPU cores.
- -XX:ZCollectionInterval: The minimum time interval between ZGC collections (in seconds).
- -XX:ZAllocationSpikeTolerance: Adjusts when ZGC triggers based on allocation spikes.
- -XX:+UnlockDiagnosticVMOptions -XX:-ZProactive: Controls proactive garbage collection behavior.
- -Xlog: Configures logging for garbage collection events.
8. ZGC Trigger Mechanisms
ZGC’s GC trigger mechanism differs significantly from CMS and G1. One of ZGC's core features is concurrency, and during the GC process, new objects may be created. The challenge lies in ensuring that the heap does not fill up before GC completes, as this could cause threads to block.
Some key ZGC triggering mechanisms are:
- Blocking Memory Allocation Requests: When the heap fills up faster than GC can handle, threads may be blocked. The keyword in logs for this is "Allocation Stall."
- Adaptive Algorithm Based on Allocation Rate: ZGC dynamically calculates when to trigger GC based on the recent allocation rate and GC times. This method helps avoid triggering too early and causing unnecessary pauses. The log keyword for this is "Allocation Rate."
- Fixed Time Intervals: ZGC can also be triggered based on fixed intervals, which is useful for burst traffic scenarios. The log keyword for this is "Timer."
- Proactive GC: When ZGC calculates that GC should happen earlier than normal, this can be triggered proactively. This can be controlled with the -ZProactive flag. Logs will show the keyword "Proactive."
- Warmup Phase: This occurs during service startup and is usually not of concern. Logs will show the keyword "Warmup."
- External Triggering: Explicit calls to System.gc() can also trigger GC, which is reflected in the logs as "System.gc()."
9. Key Innovations in ZGC
ZGC uses a combination of colored pointers, load barriers, and memory multi-mapping to achieve low-latency garbage collection.
- Colored Pointers: ZGC uses the high-order bits of a 64-bit pointer to store GC state information. These bits include flags like Marked0, Marked1, and Remapped, which indicate whether an object has been marked as live, whether it's been moved, or whether it's ready for finalization.
- Load Barriers: ZGC ensures memory consistency during object access by using load barriers. These barriers check the object's pointer color and ensure that the pointer is updated to the correct memory location if the object has been moved during GC.
- Memory Multi-Mapping: ZGC maps the same physical memory to multiple virtual addresses, each representing a different GC state (e.g., Marked0, Marked1, Remapped). This allows ZGC to efficiently switch between views of memory without actually moving data, improving flexibility and efficiency.
Conclusion
ZGC is a revolutionary step forward in Java's garbage collection strategy, particularly for applications with large heaps and low-latency requirements. By using advanced techniques like colored pointers, load barriers, and memory multi-mapping, it can achieve low pause times even with large-scale memory management. With its concurrent phases and advanced triggering mechanisms, ZGC is well-suited for cloud environments, real-time systems, and applications that require high throughput and low latency.
Top comments (0)