📜  Java的Z 垃圾收集器

📅  最后修改于: 2022-05-13 01:55:17.307000             🧑  作者: Mango

Java的Z 垃圾收集器

今天,应用程序同时响应数千甚至数百万用户是很常见的。此类应用程序需要不可估量的内存。但是,管理所有这些内存可能很容易影响应用程序性能。为了克服这个问题, Java 11 在GC(垃圾收集)域中包含了许多改进和更改。Java11 有一些很棒的功能,一个是Z Garbage Collector (ZGC) 。 Z 垃圾收集器,也称为 ZGC,是一种低延迟可扩展垃圾收集器,旨在满足以下目标。

  • 暂停时间不得超过 10 毫秒
  • 处理大小从 8MB 到 16TB 的堆
  • 暂停时间不会随着堆或实时集的大小而增加。

简而言之,Z垃圾收集器具有以下特点:

  1. 同时
  2. 基于区域
  3. 压实
  4. NUMA-aware : Non-uniform memory access (NUMA) 是一种将微处理器集群配置成多处理系统的方式,这样可以在本地共享内存,提高性能,扩展系统的能力。
  5. 使用彩色指针
  6. 使用负载屏障

(一) Z垃圾收集器的特点

  •   ZGC 并发执行所有昂贵的工作,而不会停止应用程序线程执行超过 10 毫秒,这使其非常适合需要低延迟和/或使用非常大的堆(数 TB)的应用程序。
  • ZGC在其大小和方案的配置上更加灵活。
  • ZGC 是单代 GC。它还支持部分压缩。

(B) 理解 Z 垃圾收集器

要使用 Z Garbage Collector,我们必须遵循多个步骤。您必须安装特定于 Linux/x64 的 JDK 二进制文件,然后构建并启动它。您可以使用以下命令下载 ZGC 并在您的系统上构建它:



$ hg clone http://hg.openjdk.java.net/jdk/jdk
$ cd zgc
$ sh configure --with-jvm-features=zgc
$ make images
g./build/linux-x86_64-normal-server-release/images/jdk 

(C) 实现:基本的 HelloGFG 类

Java
// Java Program to Simply Create a Demo Class
 
// Importing input output libraries
import java.io.*;
 
// Main Class
class HelloGFG {
    // Main driver method
    public static void main(String[] args)
    {
        // Print statement
        System.out.println(
            "Hello to new Garbage Collector - ZGC!");
    }
}


输出
Hello to new Garbage Collector - ZGC!

要启用基本 GC 日志记录,用户可以添加-Xlog:gc选项。在微调应用程序时,详细的日志记录很有帮助。用户可以使用-Xlog:gc*选项启用它,如下所示:

java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC HelloGFG

前面的命令会将所有日志输出到控制台,这可能会使搜索特定内容变得困难。用户可以指定要写入文件的日志如下:

java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc* HelloGFG

(D) Z 垃圾收集器堆

ZGC 将内存划分为区域,也称为 ZPages。这些可以动态创建和销毁。 ZGC 堆可以多次出现这些堆区域。中大区域是连续分配的。这些也可以动态调整大小(不像 G1 GC ),它们是 2 MB 的倍数。以下是堆区域的大小组:



Small2 MB
Medium32 MB
LargeN × 2 MB

(E) Z 垃圾收集器阶段:

ZGC 的 GC 周期分为三个暂停。

  1. 暂停标记开始:在第一阶段,ZGC 遍历对象图以标记对象的存活或垃圾。此阶段还包括重新映射实时数据。这是迄今为止 ZGC GC 周期中最繁重的工作负载之一。
  2. 暂停标记结束:第二阶段是完成参考预处理的地方。类卸载和重定位集选择也在此阶段完成。它还包括重定位集选择。 ZGC 标记要压缩的区域。
  3. 暂停重定位开始:最后一个阶段是压缩堆的繁重工作发生的地方。

(F) 彩色指针

彩色指针是 ZGC 的核心概念之一。它使 ZGC 能够查找、标记、定位和重新映射对象。它不支持 x32 平台。彩色点的实现需要虚拟地址屏蔽,这可以在硬件、操作系统或软件中完成。下图显示了 64 位指针布局:

前 18 位保留供将来使用。 42 位最多可寻址 4 TB 的地址空间。现在是剩下的,有趣的,4 位。 Marked1 和 Marked0 位用于标记对象以进行垃圾收集。通过为 Remapped 设置单个位,可以将对象标记为不指向重定位集。用于终结的最后 1 位与并发引用处理相关。它标志着一个对象只能通过终结器访问。

如上图所示,64位对象引用划分如下:

18 bitsUnused bits
1-bitFinalizable
1-bitRemapped
1-bitMarked1
1-bitMarked0
42 bitsObject Address

(G) 调整 Z 垃圾收集器

ZGC 是并发垃圾收集器。通过设置应分配给 ZGC 线程的 CPU 时间量,用户可以控制 GC 启动的频率。可以使用以下选项来实现:

java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xlog:gc:mylog.log* HelloGFG

ConcGCThreads 选项的值越高,应用程序的 CPU 时间就越少。另一方面,较低的值可能会导致您的应用程序争夺内存;您的应用程序生成的垃圾可能比 ZGC 收集的垃圾更多。 ZGC 还可以使用 ConcGCThreads 的默认值。要根据此参数微调您的应用程序,您可能更愿意针对测试值执行。



对于高级 ZGC 调整,用户还可以启用大页面以增强应用程序的性能。它可以通过使用以下选项来完成:

-XX:ConcGCThreads=

除了启用大页面,用户还可以使用以下选项启用透明大页面:

-XX:+UseLargePages

前面的选项还包括其他设置和配置,可以使用 ZGC 的官方 wiki 页面访问。

ZGC 是一个 NUMA-aware GC。在 NUMA 机器上执行的应用程序可以显着提高性能。默认情况下,ZGC 启用 NUMA 支持。但是,如果 JVM 意识到它绑定到 JVM 中的一个子集,则可以禁用此功能。要覆盖 JVM 的决定,可以使用以下选项:

-XX:+UseTransparentHugePage