ZGC 的 “Z” 的含义

这个名字最初的灵感来源于 ZFS(文件系统),向其致敬。ZFS 在首次推出时具有革命性意义,尽管它的名称起初代表“Zettabyte File System”(泽字节文件系统),但后来被官方声明为不代表任何具体含义,仅仅是一个名称。同样,ZGC 的 “Z” 也没有特定含义,它的命名沿袭了 ZFS 的风格,仅作为标识符存在。

ZGC 的 发展

jdk11开始引入zgc;jdk12支持并发类卸载和进一步的暂停时间缩短;jdk13支持的最大堆内存从 4TB 增加到 16TB,引入了 未使用内存的释放功能。当堆内存中存在未使用的部分时,ZGC 可以将这些内存返还给操作系统(uncommitting unused memory),添加了 -XX:SoftMaxHeapSize 参数,用于定义堆的软上限(Soft Maximum Heap Size),增加了对 Linux 上 AArch64 架构的支持,缩短进入安全点的时间(Reduced Time-To-Safepoint);jdk14支持更小的堆(最低可达 8MB),支持内存泄漏分析,支持并行预触(Parallel Pre-touch,需开启 -XX:+AlwaysPreTouch),通过 Clone Intrinsic 等技术,提升了对象克隆和复制操作的性能;jdk15正式成为生产就绪版本,改进 NUMA 感知能力,支持压缩类指针;jdk16并发线程栈扫描,支持原地重定位;jdk17动态调整垃圾回收线程数,减少标记栈的内存使用,支持 macOS/AArch64;jdk18支持字符串去重 (-XX:+UseStringDeduplication);jdk21支持分代垃圾回收 (-XX:+ZGenerational) ;jdk23引入分代 ZGC(Generational ZGC)并设为默认版本,修复因 ICBufferFull Safepoints 导致的延迟问题。

如何使用ZGC

ZGC 的设计具有自适应性,只需极少的手动配置。在 Java 程序执行期间,ZGC 会通过调整代数大小、扩展 GC 线程数和调整老年代阈值来动态适应工作负载。主要的调整旋钮是增加最大堆大小。ZGC 有两个版本:新版分代版本和旧版非分代版本。非分代 ZGC是 ZGC 的旧版本,它不利用分代(请参阅分代)来优化其运行时特性。建议用户过渡到使用较新的分代 ZGC。

启用分代的ZGC

-XX:+UseZGC -XX:+ZGenerational

启用非分代的ZGC

-XX:+UseZGC