18 Eylül 2019 Çarşamba

Z Garbage Collector

Giriş
Java 11 ile deneysel olarak geldi, Java 15 ile tam kullanıma girdi.

Kullanım senaryosu şöyle
 Garbage Collectors | Scenarios
====================|==========================================
 * Serial           | * Small data sets (~100 MB max)
                    | * Limited resources (e.g., single core)
                    | * Low pause times
--------------------|------------------------------------------
 * Parallel         | * Peak performance in multi-core systems
                    | * High computational loads
                    | * Greater than 1sec pauses are acceptable
--------------------|------------------------------------------
 * G1               | * Response time over throughput
 * CMS              | * Large heap
                    | * Pauses less than 1sec
--------------------|------------------------------------------
 * Shenandoah       | * Minimize pause times
                    | * Predicatable latencies
--------------------|------------------------------------------
 * ZGC              | * Response time is high-priority, and/or
                    | * Very large heap
--------------------|------------------------------------------
 * Epsilon GC       | * Performance testing and troubleshooting
Z Garbage Collector
Açıklaması şöyle.
Z GC is a scalable, low-latency garbage collector. Its goal is to keep GC pause times less than 10ms. Early access of Z GC algorithm is available in Java 11 and 12. So if your application is running on Java 11 or 12, you may consider upgrading to Z GC algorithm. 
Açıklaması şöyle. Burada en önemli nokta GC Pause süresini 10 milisaniyenin altında tutmak. Bunu da concurrent çalışmasına borçlu.  Ayrıca sadece root scanning yaptığı için stop-the-world kısa sürüyor
As a concurrent garbage collector, ZGC guarantees not to exceed application latency by 10 milliseconds, even for bigger heap sizes. ...

The stop-the-world pauses are limited to root scanning in ZGC. It uses load barriers with colored pointers to perform concurrent operations when the threads are running and they are used to keep track of heap usage. Colored pointers are one of the core concepts of ZGC and it enables ZGC to find, mark, locate, and remap the objects. Compared to G1, ZGC has better ways to deal with very large object allocations which are highly performant when it comes to reclaiming memory and reallocating it and it is a single-generation GC.

ZGC divides memory into regions, also called ZPages. These ZPages can be dynamically created and destroyed and can also be dynamically sized. Unlike other GCs, the physical heap regions of ZGC can map into a bigger heap address space (which can include virtual memory) which can avoid memory fragmentation issues.
Şu işleri concurrent yapıyor
ZGC is a concurrent low latency algorithm, it does everything concurrent (marking, compaction, reference processing, relocation set selection, StringTable cleaning, JNI WeakRef cleaning, JNI GlobalRefs scanning and class unloading), except thread stack scanning. This makes the algorithm really good for low latency.
ZGC vs G1GC
Açıklaması şöyle. Yani Humongous nesnelerde ZGC daha iyi
ZGC boasts some outstanding benchmarks when dealing with large objects.
Ne Zaman Kullanılır
Açıklaması şöyle. G1 GC'ye göre daha büyük heap alanını destekliyor.
ZGC was experimental until recent versions of the JVM. It’s designed for even larger heap sizes than G1 and is also a concurrent GC. It does support smaller environments and can be used for heap size as small as 8mb all the way to 16TB maximum heap size!

One of its biggest features is that it doesn’t pause the execution of the application for more than 10ms. The cost is a reduction in throughput.

ZGC can be enabled using the -XX:+UseZGC JVM option.
Root Scanning Thread Sayısı İle İlgili
Açıklaması şöyle
One important thing to mention is that currently, pause times do not increase with the heap or live size, however, pause times do increase with the root-set size (number of java threads that your application is using).
The ZGC Phases
Açıklaması şöyle
The GC cycle of ZGC is divided into three pauses.

- In the first phase, Pause Mark Start, ZGC walks through the object graph to mark the objects live or garbage. This phase also includes the remapping of live data.
- The second phase, Pause Mark End, is where reference preprocessing is done. The class unloading and relocation set selection are also done in this phase.
- Pause Relocate Start, the last phase, is where the heavy job of compacting the heap happens.

Reference Coloring
ZGC reference için 64 bit kullanır. Ancak bunun sadece 42 bit'i bellek adresini gösterir. Geri kalan bitler referans hakkındaki bazı bilgiler içindir. Şeklen şöyle


Açıklaması şöyle
A reference represents the position of a byte in the virtual memory. However, we don't necessarily have to use all bits of a reference to do that – some bits can represent properties of the reference. That's what we call reference coloring.

With 32 bits, we can address 4 gigabytes. Since nowadays it's widespread for a computer to have more memory than this, we obviously can't use any of these 32 bits for coloring. Therefore, ZGC uses 64-bit references. It means ZGC is only available on 64-bit platforms:

ZGC references use 42 bits to represent the address itself. As a result, ZGC references can address 4 terabytes of memory space.

On top of that, we have 4 bits to store reference states:

- finalizable bit – the object is only reachable through a finalizer
- remap bit – the reference is up to date and points to the current location of the object (see relocation)
- marked0 and marked1 bits – these are used to mark reachable objects

We also called these bits metadata bits. In ZGC, precisely one of these metadata bits is 1.
Heap Nasıldır?
Heap ZPage yapısından oluşur. Açıklaması şöyle
It is a region-based collector, which means that the heap is divided into smaller regions and the compaction efforts will be focused on a subset of those regions, the ones with the most garbage.
ZPageCache
Açıklaması şöyle. ZGC belleği işletim sistemine geri verebilir.
The ZGC heap consists of a set of heap regions called ZPages. When ZPages are emptied during a GC cycle, they are returned to the ZPageCache. ZPages in this cache are organized by least recently used order. In JDK 13, the ZGC will return pages that have been identified as unused for a sufficiently long period of time to the operating system. This allows them to be reused for other processes. Uncommitting memory will never cause the heap size to shrink below the minimum size specified on the command line. If the minimum and maximum heap sizes are set to the same value, no memory will be uncommitted.
Belleği İşletim Sistemine Geri Verme Özelliği Niye lazım ?
Açıklaması şöyle.
ZGC is an experimental low-latency garbage collector, introduced in JDK 11. ZGC's original design did not allow for memory pages to be returned to the operating system when they were no longer required; when the heap shrinks and the memory is unused for an extended period of time. For environments such as containers, where resources are shared between a number of services, this can limit the scalability and efficiency of the system.
Seçenekler
Seçenekler şöyle
-XX:ZAllocationSpikeTolerance
-XX:ZCollectionInterval
-XX:ZFragmentationLimit
-XX:ZMarkStackSpaceLimit
-XX:ZProactive
-XX:ZUncommit
-XX:ZUncommitDelay
ZUncommit seçeneği - Not Returning Unused Memory to the Operating System
Açıklaması şöyle
Unlike other GC algorithms, ZGC uncommits unused memory, giving it back to the operating system. This can be necessary for applications where memory footprint can be a problem. If you want to disable this option, you can use -XX:-ZUncommit.

-XX:+UseZGC -Xmx<size> -XX:-ZUncommit
Açıklaması şöyle
ZGC is efficiently designed to manage large heap sizes. Allocating a large heap size when application doesn’t need it can result in inefficient memory usage. By default, ZGC uncommits unused memory, returning it to the operating system. This feature can be disabled using -XX:-ZUncommit. 

ZGC ensures that memory is not uncommitted to the extent that the heap size falls below the specified minimum heap size (-Xms). Consequently, if the minimum heap size is set to match the maximum heap size (-Xmx), the uncommit feature will be implicitly disabled.

To provide flexibility in managing uncommitted memory, ZGC allows you to configure an uncommit delay using the -XX:ZUncommitDelay=<seconds> option, with a default delay of 300 seconds. This delay specifies the duration for which memory should remain unused before it becomes eligible for uncommit.
-XX:ConcGCThreads=<number>
Açıklaması şöyle
Another interesting tuning option to consider is the number of concurrent garbage collection (GC) threads in ZGC, which can be configured using the -XX:ConcGCThreads=<number> flag. ZGC has built-in heuristics to automatically select the optimal number of threads based on the characteristics of your application. The default heuristic in ZGC usually works well for most scenarios. However, depending on the specific behavior and requirements of your application, you may need to adjust the number of concurrent GC threads. This parameter determines how much CPU time is allocated to the garbage collector. Allocating too many threads can result in excessive CPU usage by the GC, taking away valuable resources from your application. On the other hand, allocating too few threads may slow down the GC performance. 

Starting from JDK 17, ZGC introduced dynamic scaling of the number of concurrent GC threads. This means that ZGC can automatically adjust the number of threads based on the workload, making it less likely for you to manually tune this parameter.
-XX:+UseLargePages - Enabling Large Pages
Açıklaması şöyle
Configuring ZGC to utilize large pages can enhance throughput, reduce latency, and improve startup time. Large pages, also known as huge pages, have a size of 2MB on Linux/x86 systems. Large pages are memory pages that are larger than the standard page size. They offer benefits such as reduced memory management overhead and improved memory access efficiency. 

To enable large pages in ZGC, you need to configure the -XX:+UseLargePages option in the JVM.  
-XX:+UseTransparentHugePages - Enabling Transparent Huge Pages
Açıklaması şöyle
An alternative to using explicit large pages (as described above) is to use Transparent Huge Pages (THP). THP is a feature in the Linux kernel that automatically aggregates standard memory pages into larger, more efficient huge pages. THP aims to improve memory management by reducing the overhead associated with managing individual pages. By grouping multiple standard pages into a single huge page (typically 2MB in size), THP can potentially enhance performance.

To enable Transparent Huge Pages in the JVM, you can use the -XX:+UseTransparentHugePages option. This allows the Java application to take advantage of the large, aggregated memory pages managed by the operating system. It’s important to note that THP may introduce latency spikes in certain scenarios, which makes it less suitable for latency-sensitive applications. Before enabling THP, it is recommended to evaluate its impact on your specific workload and performance requirements.
-XX:+UseNUMA - Enabling NUMA Support
Açıklaması şöyle
ZGC has NUMA support, which means it will try its best to direct Java heap allocations to NUMA-local memory. NUMA stands for Non-Uniform Memory Access and refers to the architecture design used in multi-socket systems. In NUMA systems, memory is divided into multiple memory nodes, with each node associated with a specific processor or socket. Each processor has faster access to its own local memory node compared to accessing remote memory nodes.

By default, ZGC enables NUMA support, allowing it to leverage the benefits of NUMA architectures. It automatically detects and utilizes local memory nodes to optimize memory access and improve performance. However, if the JVM detects that it’s bound to use memory on a single NUMA node, NUMA support will be disabled.

In most cases, you don’t need to explicitly configure NUMA support. However, if you want to override the JVM’s decision, you can use the following options:

To explicitly enable NUMA support: -XX:+UseNUMA

To explicitly disable NUMA support: -XX:-UseNUMA


Hiç yorum yok:

Yorum Gönder