Java的Z 垃圾收集器
今天,应用程序同时响应数千甚至数百万用户是很常见的。此类应用程序需要不可估量的内存。但是,管理所有这些内存可能很容易影响应用程序性能。为了克服这个问题, Java 11 在GC(垃圾收集)域中包含了许多改进和更改。Java11 有一些很棒的功能,一个是Z Garbage Collector (ZGC) 。 Z 垃圾收集器,也称为 ZGC,是一种低延迟可扩展垃圾收集器,旨在满足以下目标。
- 暂停时间不得超过 10 毫秒
- 处理大小从 8MB 到 16TB 的堆
- 暂停时间不会随着堆或实时集的大小而增加。
简而言之,Z垃圾收集器具有以下特点:
- 同时
- 基于区域
- 压实
- NUMA-aware : Non-uniform memory access (NUMA) 是一种将微处理器集群配置成多处理系统的方式,这样可以在本地共享内存,提高性能,扩展系统的能力。
- 使用彩色指针
- 使用负载屏障
(一) 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
After execution of the given commands, you can find the JDK root directory in the following location:
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!
Now, The following command can be used to enable ZGC and use it:
要启用基本 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 的倍数。以下是堆区域的大小组:
Small | 2 MB |
Medium | 32 MB |
Large | N × 2 MB |
(E) Z 垃圾收集器阶段:
ZGC 的 GC 周期分为三个暂停。
- 暂停标记开始:在第一阶段,ZGC 遍历对象图以标记对象的存活或垃圾。此阶段还包括重新映射实时数据。这是迄今为止 ZGC GC 周期中最繁重的工作负载之一。
- 暂停标记结束:第二阶段是完成参考预处理的地方。类卸载和重定位集选择也在此阶段完成。它还包括重定位集选择。 ZGC 标记要压缩的区域。
- 暂停重定位开始:最后一个阶段是压缩堆的繁重工作发生的地方。
(F) 彩色指针
彩色指针是 ZGC 的核心概念之一。它使 ZGC 能够查找、标记、定位和重新映射对象。它不支持 x32 平台。彩色点的实现需要虚拟地址屏蔽,这可以在硬件、操作系统或软件中完成。下图显示了 64 位指针布局:
前 18 位保留供将来使用。 42 位最多可寻址 4 TB 的地址空间。现在是剩下的,有趣的,4 位。 Marked1 和 Marked0 位用于标记对象以进行垃圾收集。通过为 Remapped 设置单个位,可以将对象标记为不指向重定位集。用于终结的最后 1 位与并发引用处理相关。它标志着一个对象只能通过终结器访问。
如上图所示,64位对象引用划分如下:18 bits Unused bits 1-bit Finalizable 1-bit Remapped 1-bit Marked1 1-bit Marked0 42 bits Object 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
Conclusion:
In this article, we saw that ZGC intends to support large heap sizes with low application pause times. We have briefly discussed the scalable, low latency GC for OpenJDK—ZGC. It is an experimental GC, which has been written from scratch. As a concurrent GC, it promises max latency to be less than 10 milliseconds, which doesn’t increase with heap size or live data. At present, it only works with Linux/x64. More platforms can be supported in the future if there is considerable demand for them.