ZGC 执行日志:解锁低延迟运行的核心密码

ZGC 的执行日志可以通过 JVM 参数配置输出,包含垃圾回收的阶段、时间、堆内存变化等关键信息,是分析 ZGC 运行状态、调优性能的重要依据。以下是 ZGC 日志的配置方式、关键内容解读及示例分析:

一、启用 ZGC 日志的核心参数

通过 -Xlog 系列参数控制 ZGC 日志的输出(JDK 9+ 统一日志框架),常用配置如下:

参数示例 说明
-XX:+ZPrintGC 基础日志:输出 GC 触发、阶段、耗时等关键信息(简洁版)
-XX:+ZPrintGCDetails 详细日志:包含堆区域变化、指针颜色调整、线程参与等细节
-Xlog:gc*:file=zgc.log:time,level,tags 输出到文件:将 GC 相关日志(gc*)写入 zgc.log,包含时间、级别、标签
-Xlog:gc=debug:file=zgc-debug.log 调试级日志:输出更细粒度的阶段执行细节(适合深度分析)

二、ZGC 日志的核心内容解读

ZGC 的日志按 回收周期 划分,每个周期包含多个阶段,关键信息如下:

1. 日志开头:GC 触发原因与堆状态

log 复制代码
[0.834s][info][gc] ZGC(0) Initial Mark Start (size 256M)  
  • ZGC(0):第 0 次 ZGC 回收(从 0 开始计数)。
  • Initial Mark Start:开始初始标记阶段。
  • size 256M:当前堆大小为 256MB。
  • 触发原因可能包括:Allocation Rate(内存分配速率过高)、Heap Exhausted(堆即将耗尽)等。

2. 核心阶段日志(按执行顺序)

(1)初始标记(Initial Mark)------ STW 阶段
log 复制代码
[0.835s][info][gc] ZGC(0) Initial Mark End (1.2ms)  
  • End (1.2ms):初始标记结束,耗时 1.2ms(STW 时间,极短)。
  • 作用:标记根对象(线程栈、静态变量等),为后续并发标记奠定基础。
(2)并发标记(Concurrent Mark)
log 复制代码
[0.835s][info][gc] ZGC(0) Concurrent Mark Start  
[0.842s][info][gc] ZGC(0) Concurrent Mark End (7.3ms)  
  • 全程并发执行(与应用线程同时运行),耗时 7.3ms。
  • 作用:遍历对象图,标记所有存活对象(通过着色指针标记状态)。
(3)最终标记(Final Mark)------ STW 阶段
log 复制代码
[0.842s][info][gc] ZGC(0) Final Mark Start  
[0.842s][info][gc] ZGC(0) Final Mark End (0.3ms)  
  • STW 时间 0.3ms,处理并发标记中遗漏的对象(如并发标记期间新产生的根对象)。
(4)并发预备转移(Concurrent Prepare for Relocation)
log 复制代码
[0.842s][info][gc] ZGC(0) Concurrent Prepare for Relocation Start  
[0.843s][info][gc] ZGC(0) Concurrent Prepare for Relocation End (0.9ms)  
  • 并发执行,准备需要转移的 Region(筛选出内存碎片多、存活对象少的 Region)。
(5)初始转移(Initial Relocate)------ STW 阶段
log 复制代码
[0.843s][info][gc] ZGC(0) Initial Relocate Start  
[0.843s][info][gc] ZGC(0) Initial Relocate End (0.2ms)  
  • 极短 STW(0.2ms),转移根对象直接引用的对象(为并发转移铺路)。
(6)并发转移(Concurrent Relocate)
log 复制代码
[0.843s][info][gc] ZGC(0) Concurrent Relocate Start  
[0.851s][info][gc] ZGC(0) Concurrent Relocate End (8.1ms)  
  • 并发执行,将存活对象从旧 Region 转移到新 Region(压缩内存,避免碎片),通过着色指针和读屏障保证应用线程访问正确地址。
(7)并发清理(Concurrent Cleanup)
log 复制代码
[0.851s][info][gc] ZGC(0) Concurrent Cleanup Start  
[0.852s][info][gc] ZGC(0) Concurrent Cleanup End (0.5ms)  
  • 并发回收空 Region(已完成对象转移的旧 Region),释放内存供下次分配。

3. 周期总结:总耗时与堆变化

log 复制代码
[0.852s][info][gc] ZGC(0) Heap After GC: 128M used, 384M capacity (1.5s)  
  • Heap After GC:GC 后堆使用量 128MB,总容量 384MB。
  • 整个 GC 周期耗时 1.5s(主要是并发阶段,STW 总耗时仅 ~2ms)。

三、关键指标与分析重点

  1. STW 时间 :关注 Initial Mark、Final Mark、Initial Relocate 三个阶段的耗时,正常应 <10ms,若超标可能需调优堆大小或 GC 线程数。
  2. GC 频率 :短时间内频繁触发 GC(如每秒多次),可能是内存分配速率过高或堆过小,需增大堆(-Xmx)或优化对象创建。
  3. 堆使用率 :Heap After GC 的使用率若持续超过 70%,可能导致 GC 频繁,建议调整堆大小或 ZMaxHeapSizePercent(默认 90%)。
  4. 转移效率 :Concurrent Relocate 耗时过长,可能是存活对象过多(需优化对象生命周期)或 CPU 资源不足(增加 GC 线程:-XX:ZGCThreads=n)。

四、实战示例:通过日志定位问题

若日志中频繁出现:

log 复制代码
[5.210s][warn][gc] ZGC(10) Heap exhausted, starting GC immediately  

说明堆内存即将耗尽,GC 被迫紧急触发,可能原因:

  • 堆大小不足(需增大 -Xmx);
  • 存在内存泄漏(需结合内存快照分析大对象)。

通过配置 ZGC 日志并聚焦上述关键信息,可有效评估其低延迟特性、定位性能瓶颈,为调优提供数据支撑。

相关推荐
考研保研资料分享2 小时前
2022旅游管理跨保华东师大人文地理:五场面试与择校复盘
面试·旅游
怕浪猫12 小时前
外包和大厂的前端代码,差在凌晨三点
前端·面试·github
十年Java程序媛18 小时前
Java this 与 super 详解|继承高频踩坑 + 面试题整理
java·spring boot·面试
萧瑟余晖18 小时前
Spring Cloud配置中心与动态刷新详解
spring cloud·面试
白露与泡影20 小时前
一线 Java 后端面试八股(2026 更新版,含完整答案)
java·开发语言·面试
学到老活到老1 天前
集合换成线程安全的,就不用加锁了吗?
java·面试
萧瑟余晖1 天前
Spring Cloud Alibaba生态整合详解
spring·spring cloud·面试
Sailing1 天前
【封闭结束2】Agent 意图识别:从语义理解到稳定路由
人工智能·面试·agent
Sailing1 天前
【封闭结束1】端到端交付:Agent 一次请求如何走完全链路
人工智能·面试·agent
怕浪猫1 天前
红利窗口开着,程序员别在场边囤课
面试·github·ai编程