Skip to content

ZGC(Z 垃圾回收器)

概述

ZGC(Z Garbage Collector)是 Oracle 开发的一款超低延迟垃圾回收器,设计目标是在任何堆大小下都能实现毫秒级的停顿时间。ZGC 采用了革命性的并发回收技术,包括并发标记、并发重定位和并发引用处理,几乎所有的垃圾回收工作都与应用线程并发执行。从 JDK 15 开始,ZGC 正式成为生产就绪的垃圾回收器。

基本特征

核心特点

  • 超低延迟:停顿时间始终保持在 10ms 以下
  • 可扩展性:支持 8MB 到 16TB 的堆内存
  • 并发回收:几乎所有回收工作都与应用并发执行
  • 内存效率:使用着色指针和负载屏障技术
  • NUMA 感知:针对 NUMA 架构优化

适用场景

  • 超大内存应用:堆内存 32GB 以上
  • 极低延迟要求:金融交易、实时系统
  • 云原生应用:容器化、微服务架构
  • 大数据处理:需要处理大量数据的应用

核心技术

1. 着色指针(Colored Pointers)

ZGC 的核心创新是着色指针技术,将 GC 信息直接编码在指针中:

64 位着色指针布局(Linux x86_64):
┌─────────────────────────────────────────────────────────────┐
│ 63  62  61  60  59  58  57  56  55 ... 18  17 ... 0        │
│ │   │   │   │   │   │   │   │   │         │                │
│ │   │   │   │   │   │   │   │   │         └─ 对象地址      │
│ │   │   │   │   │   │   │   │   └─────────── 未使用位      │
│ │   │   │   │   │   │   │   └─────────────── Finalizable   │
│ │   │   │   │   │   │   └─────────────────── Remapped      │
│ │   │   │   │   │   └─────────────────────── Marked1       │
│ │   │   │   │   └─────────────────────────── Marked0       │
│ │   │   │   └─────────────────────────────── 未使用位      │
│ │   │   └─────────────────────────────────── 未使用位      │
│ │   └─────────────────────────────────────── 未使用位      │
│ └─────────────────────────────────────────── 符号位        │
└─────────────────────────────────────────────────────────────┘

着色位含义:
- Marked0/Marked1:标记位,用于并发标记
- Remapped:重映射位,表示对象是否已重定位
- Finalizable:终结化位,表示对象是否需要终结化

优势:
- 无需额外的标记位图
- 支持并发标记和重定位
- 快速的对象状态检查
- 减少内存开销

2. 负载屏障(Load Barriers)

ZGC 使用负载屏障来处理并发访问和对象重定位:

java
// ZGC 负载屏障示例
public class ZGCLoadBarrier {
    
    // 原始的对象访问
    public Object getField(Object obj) {
        return obj.field;  // 编译器会插入负载屏障
    }
    
    // 负载屏障的概念实现
    public Object loadBarrier(Object ref) {
        // 1. 检查着色位
        if (needsSlowPath(ref)) {
            // 2. 进入慢路径处理
            return slowPath(ref);
        }
        // 3. 快路径:直接返回
        return ref;
    }
    
    private boolean needsSlowPath(Object ref) {
        // 检查着色位是否匹配当前 GC 阶段
        long colorBits = extractColorBits(ref);
        long expectedColor = getCurrentGCPhaseColor();
        return (colorBits & expectedColor) == 0;
    }
    
    private Object slowPath(Object ref) {
        // 慢路径处理:
        // 1. 标记对象(如果在标记阶段)
        // 2. 重定位对象(如果在重定位阶段)
        // 3. 更新引用
        
        if (isMarkingPhase()) {
            markObject(ref);
        }
        
        if (isRelocationPhase()) {
            ref = relocateObject(ref);
        }
        
        return ref;
    }
}

3. 区域管理(Region Management)

ZGC 将堆内存划分为不同大小的区域:

ZGC 区域大小分类:

1. 小区域(Small Regions):
   - 大小:2MB
   - 用途:存储小于 32KB 的对象
   - 特点:高密度存储,减少碎片

2. 中等区域(Medium Regions):
   - 大小:32MB
   - 用途:存储 32KB - 16MB 的对象
   - 特点:平衡存储密度和管理开销

3. 大区域(Large Regions):
   - 大小:动态分配(2MB 的倍数)
   - 用途:存储超过 16MB 的大对象
   - 特点:每个对象独占一个或多个区域

区域状态:
- Empty:空闲区域
- Allocating:正在分配的区域
- Relocating:正在重定位的区域
- In-Use:正在使用的区域

工作流程

ZGC 的垃圾回收过程完全并发,包含以下主要阶段:

1. 并发标记(Concurrent Marking)

并发标记详细流程:

1. 根扫描(Root Scanning):
   - 扫描 GC Roots(栈、全局变量等)
   - 标记直接可达的对象
   - 使用着色指针标记对象
   - 停顿时间:< 1ms

2. 并发标记遍历(Concurrent Mark Traversal):
   - 遍历对象图,标记所有可达对象
   - 使用负载屏障处理并发修改
   - 应用线程继续正常运行
   - 标记信息存储在着色指针中

3. 标记完成(Mark Completion):
   - 处理剩余的标记工作
   - 统计存活对象信息
   - 为重定位阶段做准备
   - 停顿时间:< 1ms

标记算法特点:
- 使用三色标记算法
- 通过着色指针避免标记位图
- 支持增量标记
- 处理并发修改

2. 并发重定位(Concurrent Relocation)

并发重定位详细流程:

1. 重定位集选择(Relocation Set Selection):
   - 选择需要回收的区域
   - 优先选择垃圾最多的区域
   - 考虑重定位成本和收益
   - 停顿时间:< 1ms

2. 并发重定位(Concurrent Relocation):
   - 将存活对象移动到新区域
   - 更新对象的着色指针
   - 建立转发表(Forwarding Table)
   - 应用线程继续正常运行

3. 引用更新(Reference Update):
   - 通过负载屏障延迟更新引用
   - 在下次访问时更新引用
   - 避免遍历整个堆
   - 减少停顿时间

重定位特点:
- 完全并发执行
- 使用转发表跟踪对象移动
- 延迟引用更新
- 支持 NUMA 优化

3. 并发引用处理(Concurrent Reference Processing)

并发引用处理流程:

1. 弱引用处理:
   - 处理 WeakReference 对象
   - 清理不可达的弱引用
   - 并发执行,不影响应用

2. 软引用处理:
   - 根据内存压力处理 SoftReference
   - 考虑对象的访问时间
   - 平衡内存使用和性能

3. 虚引用处理:
   - 处理 PhantomReference 对象
   - 通知对象即将被回收
   - 支持资源清理

4. 终结化处理:
   - 处理需要 finalize 的对象
   - 调用 finalize 方法
   - 延迟对象回收

算法实现

ZGC 主要算法

java
// ZGC 垃圾回收器主要算法实现
public class ZGarbageCollector {
    private final ZHeap heap;
    private final ZBarrierSet barrierSet;
    private final ZRelocationSet relocationSet;
    private final ZForwardingTable forwardingTable;
    
    // ZGC 回收的主要入口
    public void collect() {
        try {
            // 1. 并发标记阶段
            concurrentMark();
            
            // 2. 并发重定位准备
            prepareRelocation();
            
            // 3. 并发重定位
            concurrentRelocate();
            
            // 4. 并发引用处理
            concurrentReferenceProcessing();
            
        } catch (Exception e) {
            // 处理异常
            handleGCException(e);
        }
    }
    
    // 并发标记实现
    private void concurrentMark() {
        // 1. 根扫描(短暂停顿)
        pauseAndScanRoots();
        
        // 2. 并发标记遍历
        concurrentMarkTraversal();
        
        // 3. 标记完成(短暂停顿)
        pauseAndFinishMarking();
    }
    
    private void pauseAndScanRoots() {
        // 短暂停顿,扫描 GC Roots
        stopAllApplicationThreads();
        
        try {
            // 扫描栈、全局变量等根对象
            for (GCRoot root : getAllGCRoots()) {
                Object obj = root.getObject();
                if (obj != null) {
                    markObject(obj);
                }
            }
            
            // 初始化标记队列
            initializeMarkingQueues();
            
        } finally {
            resumeAllApplicationThreads();
        }
    }
    
    private void concurrentMarkTraversal() {
        // 并发标记遍历
        while (hasUnprocessedObjects()) {
            Object obj = getNextUnprocessedObject();
            
            if (obj != null && isMarked(obj)) {
                // 扫描对象的引用
                scanObjectReferences(obj);
            }
            
            // 让出 CPU 时间
            if (shouldYield()) {
                Thread.yield();
            }
        }
    }
    
    private void scanObjectReferences(Object obj) {
        // 扫描对象的所有引用字段
        for (Object ref : obj.getReferences()) {
            if (ref != null) {
                // 通过负载屏障处理引用
                ref = loadBarrier(ref);
                
                // 标记引用的对象
                if (!isMarked(ref)) {
                    markObject(ref);
                }
            }
        }
    }
    
    // 并发重定位实现
    private void concurrentRelocate() {
        // 1. 选择重定位集合(短暂停顿)
        pauseAndSelectRelocationSet();
        
        // 2. 并发重定位对象
        concurrentRelocateObjects();
    }
    
    private void pauseAndSelectRelocationSet() {
        stopAllApplicationThreads();
        
        try {
            // 选择需要回收的区域
            relocationSet.clear();
            
            for (ZRegion region : heap.getAllRegions()) {
                if (shouldRelocateRegion(region)) {
                    relocationSet.add(region);
                }
            }
            
            // 初始化转发表
            forwardingTable.initialize(relocationSet);
            
        } finally {
            resumeAllApplicationThreads();
        }
    }
    
    private void concurrentRelocateObjects() {
        // 并发重定位对象
        for (ZRegion region : relocationSet.getRegions()) {
            relocateRegion(region);
        }
    }
    
    private void relocateRegion(ZRegion region) {
        // 遍历区域中的所有存活对象
        for (Object obj : region.getLiveObjects()) {
            // 分配新的内存空间
            Object newObj = heap.allocateObject(obj.getSize());
            
            // 复制对象内容
            copyObjectContent(obj, newObj);
            
            // 更新转发表
            forwardingTable.setForwarding(obj, newObj);
            
            // 更新着色指针
            updateColoredPointer(newObj);
        }
        
        // 释放原区域
        heap.freeRegion(region);
    }
}

负载屏障实现

java
// ZGC 负载屏障详细实现
public class ZLoadBarrier {
    private final ZGCPhase currentPhase;
    private final ZForwardingTable forwardingTable;
    private final ZMarkingContext markingContext;
    
    // 负载屏障主入口
    public Object loadBarrier(Object ref) {
        if (ref == null) {
            return null;
        }
        
        // 快路径:检查着色位
        if (isFastPath(ref)) {
            return ref;
        }
        
        // 慢路径:需要特殊处理
        return slowPath(ref);
    }
    
    private boolean isFastPath(Object ref) {
        // 检查着色位是否匹配当前 GC 阶段
        long colorBits = extractColorBits(ref);
        long expectedColor = getExpectedColor();
        
        return (colorBits & expectedColor) != 0;
    }
    
    private Object slowPath(Object ref) {
        // 根据当前 GC 阶段处理
        switch (currentPhase) {
            case MARKING:
                return markingSlowPath(ref);
            case RELOCATION:
                return relocationSlowPath(ref);
            default:
                return ref;
        }
    }
    
    private Object markingSlowPath(Object ref) {
        // 标记阶段的慢路径
        if (!isMarked(ref)) {
            // 标记对象
            markObject(ref);
            
            // 更新着色指针
            ref = updateMarkingColor(ref);
        }
        
        return ref;
    }
    
    private Object relocationSlowPath(Object ref) {
        // 重定位阶段的慢路径
        Object forwardedRef = forwardingTable.getForwarding(ref);
        
        if (forwardedRef != null) {
            // 对象已被重定位
            return forwardedRef;
        }
        
        // 检查对象是否在重定位集合中
        if (isInRelocationSet(ref)) {
            // 需要重定位对象
            return relocateObject(ref);
        }
        
        // 更新着色指针
        return updateRelocationColor(ref);
    }
    
    private Object relocateObject(Object ref) {
        // 同步重定位对象
        synchronized (ref) {
            // 再次检查是否已被重定位
            Object forwardedRef = forwardingTable.getForwarding(ref);
            if (forwardedRef != null) {
                return forwardedRef;
            }
            
            // 分配新内存
            Object newRef = allocateNewObject(ref.getSize());
            
            // 复制对象内容
            copyObjectContent(ref, newRef);
            
            // 更新转发表
            forwardingTable.setForwarding(ref, newRef);
            
            // 更新着色指针
            newRef = updateRelocationColor(newRef);
            
            return newRef;
        }
    }
    
    // 着色指针操作
    private long extractColorBits(Object ref) {
        long address = getObjectAddress(ref);
        return address & COLOR_MASK;
    }
    
    private Object updateMarkingColor(Object ref) {
        long address = getObjectAddress(ref);
        long newAddress = (address & ~COLOR_MASK) | MARKED_COLOR;
        return getObjectFromAddress(newAddress);
    }
    
    private Object updateRelocationColor(Object ref) {
        long address = getObjectAddress(ref);
        long newAddress = (address & ~COLOR_MASK) | REMAPPED_COLOR;
        return getObjectFromAddress(newAddress);
    }
}

区域管理实现

java
// ZGC 区域管理实现
public class ZRegionManager {
    private final List<ZRegion> smallRegions;
    private final List<ZRegion> mediumRegions;
    private final List<ZRegion> largeRegions;
    private final ZRegionAllocator allocator;
    
    public ZRegionManager(long heapSize) {
        this.smallRegions = new ArrayList<>();
        this.mediumRegions = new ArrayList<>();
        this.largeRegions = new ArrayList<>();
        this.allocator = new ZRegionAllocator(heapSize);
        
        initializeRegions();
    }
    
    private void initializeRegions() {
        // 初始化不同大小的区域
        long totalSize = allocator.getTotalSize();
        
        // 分配小区域(2MB)
        int smallRegionCount = (int) (totalSize * 0.6 / SMALL_REGION_SIZE);
        for (int i = 0; i < smallRegionCount; i++) {
            ZRegion region = allocator.allocateRegion(SMALL_REGION_SIZE);
            smallRegions.add(region);
        }
        
        // 分配中等区域(32MB)
        int mediumRegionCount = (int) (totalSize * 0.3 / MEDIUM_REGION_SIZE);
        for (int i = 0; i < mediumRegionCount; i++) {
            ZRegion region = allocator.allocateRegion(MEDIUM_REGION_SIZE);
            mediumRegions.add(region);
        }
        
        // 剩余空间用于大区域
        long remainingSize = totalSize - 
            (smallRegionCount * SMALL_REGION_SIZE) - 
            (mediumRegionCount * MEDIUM_REGION_SIZE);
        
        if (remainingSize > 0) {
            ZRegion region = allocator.allocateRegion(remainingSize);
            largeRegions.add(region);
        }
    }
    
    public ZRegion allocateRegion(long objectSize) {
        if (objectSize <= SMALL_OBJECT_THRESHOLD) {
            return allocateSmallRegion();
        } else if (objectSize <= MEDIUM_OBJECT_THRESHOLD) {
            return allocateMediumRegion();
        } else {
            return allocateLargeRegion(objectSize);
        }
    }
    
    private ZRegion allocateSmallRegion() {
        for (ZRegion region : smallRegions) {
            if (region.getState() == RegionState.EMPTY) {
                region.setState(RegionState.ALLOCATING);
                return region;
            }
        }
        
        // 没有可用的小区域,尝试分配新区域
        ZRegion newRegion = allocator.allocateRegion(SMALL_REGION_SIZE);
        if (newRegion != null) {
            smallRegions.add(newRegion);
            newRegion.setState(RegionState.ALLOCATING);
            return newRegion;
        }
        
        return null;
    }
    
    private ZRegion allocateMediumRegion() {
        for (ZRegion region : mediumRegions) {
            if (region.getState() == RegionState.EMPTY) {
                region.setState(RegionState.ALLOCATING);
                return region;
            }
        }
        
        // 没有可用的中等区域,尝试分配新区域
        ZRegion newRegion = allocator.allocateRegion(MEDIUM_REGION_SIZE);
        if (newRegion != null) {
            mediumRegions.add(newRegion);
            newRegion.setState(RegionState.ALLOCATING);
            return newRegion;
        }
        
        return null;
    }
    
    private ZRegion allocateLargeRegion(long objectSize) {
        // 大对象需要专门的区域
        long regionSize = alignToRegionSize(objectSize);
        ZRegion newRegion = allocator.allocateRegion(regionSize);
        
        if (newRegion != null) {
            largeRegions.add(newRegion);
            newRegion.setState(RegionState.ALLOCATING);
            return newRegion;
        }
        
        return null;
    }
    
    public void freeRegion(ZRegion region) {
        region.clear();
        region.setState(RegionState.EMPTY);
        
        // 可以考虑将区域返回给操作系统
        if (shouldReturnToOS(region)) {
            allocator.deallocateRegion(region);
            removeRegionFromList(region);
        }
    }
    
    private boolean shouldReturnToOS(ZRegion region) {
        // 根据内存压力和区域使用情况决定
        return allocator.getMemoryPressure() < LOW_MEMORY_THRESHOLD &&
               region.getSize() >= LARGE_REGION_SIZE;
    }
}

性能特征

优势

  1. 超低延迟

    • 停顿时间始终 < 10ms
    • 与堆大小无关的停顿时间
    • 适合延迟敏感应用
  2. 高可扩展性

    • 支持 8MB 到 16TB 堆内存
    • 线性扩展性能
    • NUMA 架构优化
  3. 并发性能

    • 几乎所有工作都并发执行
    • 最小化应用线程停顿
    • 高效的负载屏障
  4. 内存效率

    • 着色指针技术减少元数据
    • 区域化管理减少碎片
    • 支持内存压缩

劣势

  1. 内存开销

    • 着色指针需要 64 位平台
    • 负载屏障有一定开销
    • 转发表占用内存
  2. 吞吐量影响

    • 负载屏障影响应用性能
    • 并发回收消耗 CPU 资源
    • 可能低于 G1 GC 的吞吐量
  3. 平台限制

    • 仅支持 64 位平台
    • 需要操作系统支持
    • 某些平台特性可能不可用

JVM 参数配置

基础参数

bash
# 启用 ZGC
-XX:+UseZGC                     # 启用 ZGC 垃圾回收器

# 堆内存设置
-Xms32g                         # 初始堆大小
-Xmx128g                        # 最大堆大小

# ZGC 特定参数
-XX:SoftMaxHeapSize=120g        # 软最大堆大小

ZGC 核心参数

bash
# 并发线程数
-XX:ConcGCThreads=12            # 并发 GC 线程数

# 内存管理
-XX:ZCollectionInterval=5       # GC 间隔时间(秒)
-XX:ZUncommitDelay=300          # 内存归还延迟(秒)

# 大对象处理
-XX:ZLargeObjectSizeThreshold=32m  # 大对象阈值

高级参数

bash
# 性能调优
-XX:+UseLargePages              # 使用大页内存
-XX:+UseTransparentHugePages    # 使用透明大页

# NUMA 优化
-XX:+UseNUMA                    # 启用 NUMA 感知

# 调试参数
-XX:+PrintGC                    # 打印 GC 信息
-XX:+PrintGCDetails             # 打印详细 GC 信息
-Xlog:gc*:gc.log                # GC 日志输出

JDK 版本特定参数

bash
# JDK 11-14(实验性)
-XX:+UnlockExperimentalVMOptions
-XX:+UseZGC

# JDK 15+(生产就绪)
-XX:+UseZGC

# JDK 17+(增强特性)
-XX:+UseZGC
-XX:+ZGenerational              # 分代 ZGC(实验性)

监控与调优

关键指标

  1. 延迟指标

    • 最大停顿时间
    • 平均停顿时间
    • 停顿时间分布
  2. 吞吐量指标

    • 应用吞吐量
    • GC 开销占比
    • 内存分配速率
  3. 内存指标

    • 堆内存使用率
    • 区域分配情况
    • 内存回收效率

调优策略

延迟优化

bash
# 减少停顿时间
-XX:ConcGCThreads=16            # 增加并发线程数
-XX:+UseLargePages              # 使用大页减少 TLB 开销
-XX:ZCollectionInterval=1       # 更频繁的 GC

吞吐量优化

bash
# 提高吞吐量
-XX:ConcGCThreads=8             # 减少并发线程数
-XX:ZCollectionInterval=10      # 减少 GC 频率
-XX:SoftMaxHeapSize=90%         # 设置软最大堆大小

内存优化

bash
# 内存使用优化
-XX:ZUncommitDelay=60           # 快速归还内存
-XX:+UseTransparentHugePages    # 使用透明大页
-XX:ZLargeObjectSizeThreshold=16m  # 调整大对象阈值

监控工具

JVM 内置工具

bash
# 查看 ZGC 统计
jstat -gc <pid> 1s

# 查看详细信息
jcmd <pid> GC.run

# 查看内存使用
jcmd <pid> VM.memory

# 查看 ZGC 特定信息
jcmd <pid> GC.run_finalization

GC 日志分析

bash
# 启用详细 ZGC 日志
-Xlog:gc*:gc.log:time,tags

# 关注的日志信息:
# - [gc] GC(N) Pause Mark Start
# - [gc] GC(N) Concurrent Mark
# - [gc] GC(N) Pause Mark End
# - [gc] GC(N) Concurrent Relocation

典型应用场景

1. 金融交易系统

bash
# 超低延迟交易系统配置
-XX:+UseZGC
-Xms64g -Xmx256g
-XX:SoftMaxHeapSize=240g
-XX:ConcGCThreads=16
-XX:+UseLargePages
-XX:+UseNUMA
-XX:ZCollectionInterval=1

2. 大数据处理

bash
# 大数据处理系统配置
-XX:+UseZGC
-Xms128g -Xmx512g
-XX:SoftMaxHeapSize=480g
-XX:ConcGCThreads=32
-XX:ZLargeObjectSizeThreshold=64m
-XX:+UseTransparentHugePages

3. 云原生应用

bash
# 容器化应用配置
-XX:+UseZGC
-Xms16g -Xmx64g
-XX:SoftMaxHeapSize=60g
-XX:ConcGCThreads=8
-XX:ZUncommitDelay=60
-XX:+UseContainerSupport

与其他 GC 对比

特性ZGCG1 GCCMS GCParallel GC
停顿时间< 10ms可控
吞吐量中等中等最高
内存开销中高中等
堆大小支持8MB-16TB4GB-64GB4GB-32GB< 32GB
并发程度极高部分
平台要求64位通用通用通用
成熟度较新成熟成熟成熟
复杂度中等简单

最佳实践

1. 选择标准

  • 延迟要求:需要极低延迟(< 10ms)
  • 堆内存大小:32GB 以上
  • 平台支持:64 位 Linux/Windows
  • 应用特性:延迟敏感的服务

2. 配置建议

  • 合理设置堆大小:避免过小的堆内存
  • 启用大页内存:减少 TLB 开销
  • 调整并发线程数:根据 CPU 核数调整
  • 监控内存使用:避免内存压力过大

3. 注意事项

  • 评估吞吐量影响:ZGC 可能降低吞吐量
  • 测试应用兼容性:验证应用在 ZGC 下的行为
  • 监控系统资源:关注 CPU 和内存使用
  • 定期性能测试:验证延迟和吞吐量指标

4. 迁移建议

  • 从 G1 迁移:当延迟成为主要瓶颈时
  • 从 CMS 迁移:当需要更好的可扩展性时
  • 渐进式迁移:先在测试环境验证

故障排查

常见问题

  1. 吞吐量下降

    原因:负载屏障开销或并发 GC 消耗 CPU
    解决:
    - 调整并发线程数
    - 优化应用代码
    - 考虑其他 GC 算法
  2. 内存使用过高

    原因:着色指针和转发表开销
    解决:
    - 增加堆内存
    - 调整 SoftMaxHeapSize
    - 优化对象生命周期
  3. GC 频率过高

    原因:内存分配速率过快
    解决:
    - 增加 ZCollectionInterval
    - 优化内存分配
    - 调整堆大小

诊断工具

bash
# 分析 GC 日志
-Xlog:gc*:gc.log:time,tags

# 监控内存使用
jstat -gc <pid> 1s

# 分析堆转储
jmap -dump:format=b,file=heap.hprof <pid>

# 查看 ZGC 内部状态
jcmd <pid> GC.run_finalization

发展历程与未来

历史发展

  • JDK 11:首次引入 ZGC(实验性)
  • JDK 13:支持归还未使用内存给操作系统
  • JDK 14:支持 macOS 和 Windows
  • JDK 15:ZGC 正式生产就绪
  • JDK 17:引入分代 ZGC(实验性)

未来发展

  • 分代收集:支持分代垃圾回收
  • 性能优化:继续优化吞吐量和延迟
  • 平台扩展:支持更多平台和架构
  • 易用性改进:简化配置和调优

总结

ZGC 是一个革命性的垃圾回收器,它通过着色指针和负载屏障技术实现了超低延迟的垃圾回收。虽然它在吞吐量方面可能不如传统的垃圾回收器,但对于延迟敏感的应用来说,ZGC 提供了无与伦比的性能保证。随着技术的不断发展和优化,ZGC 将成为大内存、低延迟应用的首选垃圾回收器。对于需要极致性能的现代应用,ZGC 代表了垃圾回收技术的未来方向。