读懂G1 GC日志关键在于分析内存行为节奏与停顿原因,需重点关注暂停类型、各代空间变化及真实停顿时间(real),识别如Survivor占用高位、Full GC后老年代未释放、to-space exhausted等异常模式。

看懂 G1 GC 日志,关键不是数“GC 次数”,而是读懂内存行为的节奏和停顿背后的线索。它像一份实时体检报告,反映的是 Eden 填充速度、对象存活率、晋升是否异常、老年代压力是否累积——这些信号藏在每行日志的字段组合里。
先抓三类核心字段
一行典型 G1 日志如:
2024-03-15T14:23:01.123+0800: 34567.890: [GC pause (G1 Evacuation Pause) (young), 0.123ms] [Eden: 1024M(1024M)->0B, Survivors: 128M->128M, Heap: 1840M(4096M)->820M(4096M)]
- 暂停类型与原因:括号内内容比“GC”二字重要得多。“G1 Evacuation Pause (young)”说明是年轻代疏散;“Allocation Failure”表示 Eden 满了触发;“Metadata GC Threshold”指向元空间不足;“G1 Humongous Allocation”提示超大对象分配失败。
- 各代空间变化:关注箭头左右数值。“Eden: 1024M→0B”说明回收干净;“Survivors: 128M→128M”不变,可能 Survivor 空间过小或对象年龄阈值太低,导致大量对象直接晋升;“Heap: 1840M→820M”整体下降约 1GB,但若后续几轮中 Heap 使用量持续回升且 Survivor 占用不降,就提示对象存活率高或晋升策略不合理。
- 真实停顿时间(real):如 real=0.123ms,这是 STW 实际耗时,直接影响请求延迟。user/sys 是 CPU 开销,real 才是服务感知到的卡顿。若 real 频繁超过 10ms(尤其对低延迟服务),需排查并发失败、Mixed GC 耗时突增或 Region 不足等问题。
识别真正危险的异常模式
高频 Full GC 往往只是表象,背后隐藏更深层问题:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- Minor GC 后 Eden 几乎归零,但 Survivor 占用持续高位 → Survivor 区太小,或
-XX:MaxTenuringThreshold设得太低,对象被迫提前晋升。 - Full GC 后老年代使用量未下降,甚至略升 → 存在内存泄漏(如静态 Map 持有业务对象)、缓存未清理,或大对象(Humongous Object)长期驻留。
- 反复出现 to-space exhausted 或 evacuation failed → G1 Region 不足,或
-XX:G1HeapRegionSize设置不当,需检查是否存在超大数组/ByteBuffer。 - Minor GC 频率陡增(如从每 5 秒一次变成每 200ms 一次),而 QPS 无明显上升 → 代码中突发创建大量短生命周期对象,比如循环内 new 对象、未复用 StringBuilder 等。
日志开启与常用参数
要获得可分析的日志,启动时至少配置:
-
-Xloggc:/path/to/gc.log:指定输出路径 -
-XX:+PrintGCDetails:显示 Eden/Survivor/Heap 变化、GC 原因、各阶段耗时 -
-XX:+PrintGCDateStamps:带标准时间戳,便于关联业务日志 -
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=14 -XX:GCLogFileSize=20M:自动轮转,防止单文件过大 -
-XX:+PrintHeapAtGC:每次 GC 前后打印堆详情,辅助定位内存分布问题
借助工具提升效率
人工逐行扫日志效率低,推荐用成熟工具辅助:










