G1 Mixed GC 完整周期分析
一、完整日志片段
以下是从生产环境 GC 日志中提取的一个完整的 Mixed GC 周期,包括并发标记、准备阶段和三次 Mixed GC 回收。
[2026-10-12T14:01:24.881+0800][14912][gc ] GC(19174) Pause Young (Concurrent Start) (G1 Evacuation Pause) 10927M->5557M(12288M) 15.951ms
[2026-10-12T14:01:24.881+0800][14908][gc ] GC(19175) Concurrent Mark Cycle
[2026-10-12T14:01:24.883+0800][14908][gc,marking ] GC(19175) Concurrent Clear Claimed Marks
[2026-10-12T14:01:24.884+0800][14908][gc,marking ] GC(19175) Concurrent Clear Claimed Marks 3.236ms
[2026-10-12T14:01:24.884+0800][14908][gc,marking ] GC(19175) Concurrent Scan Root Regions
[2026-10-12T14:01:24.892+0800][14908][gc,marking ] GC(19175) Concurrent Scan Root Regions 8.036ms
[2026-10-12T14:01:24.892+0800][14908][gc,marking ] GC(19175) Concurrent Mark
[2026-10-12T14:01:24.892+0800][14908][gc,marking ] GC(19175) Concurrent Mark From Roots
[2026-10-12T14:01:24.892+0800][14908][gc,task ] GC(19175) Using 2 workers of 2 for marking
[2026-10-12T14:01:25.070+0800][14908][gc,marking ] GC(19175) Concurrent Mark From Roots 177.877ms
[2026-10-12T14:01:25.070+0800][14908][gc,marking ] GC(19175) Concurrent Preclean
[2026-10-12T14:01:25.072+0800][14908][gc,marking ] GC(19175) Concurrent Preclean 2.111ms
[2026-10-12T14:01:25.073+0800][14912][gc,start ] GC(19175) Pause Remark
[2026-10-12T14:01:25.196+0800][14912][gc ] GC(19175) Pause Remark 5578M->3834M(12288M) 123.072ms
[2026-10-12T14:01:25.196+0800][14908][gc,marking ] GC(19175) Concurrent Mark 303.635ms
[2026-10-12T14:01:25.196+0800][14908][gc,marking ] GC(19175) Concurrent Rebuild Remembered Sets
[2026-10-12T14:01:25.360+0800][14908][gc,marking ] GC(19175) Concurrent Rebuild Remembered Sets 164.177ms
[2026-10-12T14:01:25.360+0800][14912][gc,start ] GC(19175) Pause Cleanup
[2026-10-12T14:01:25.361+0800][14912][gc ] GC(19175) Pause Cleanup 3874M->3874M(12288M) 0.599ms
[2026-10-12T14:01:25.413+0800][14908][gc,marking ] GC(19175) Concurrent Cleanup for Next Mark 51.329ms
[2026-10-12T14:01:25.413+0800][14908][gc ] GC(19175) Concurrent Mark Cycle 531.694ms
[2026-10-12T14:02:32.477+0800][14912][gc,start ] GC(19176) Pause Young (Prepare Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:32.490+0800][14912][gc,heap ] GC(19176) Eden regions: 671->0(72)
[2026-10-12T14:02:32.490+0800][14912][gc,heap ] GC(19176) Survivor regions: 4->4(85)
[2026-10-12T14:02:32.490+0800][14912][gc,heap ] GC(19176) Old regions: 473->473
[2026-10-12T14:02:32.490+0800][14912][gc,metaspace] GC(19176) Metaspace: 161176K(177216K)->161176K(177216K)
[2026-10-12T14:02:32.490+0800][14912][gc ] GC(19176) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 9181M->3816M(12288M) 13.650ms
[2026-10-12T14:02:38.600+0800][14912][gc,start ] GC(19177) Pause Young (Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:38.610+0800][14912][gc,heap ] GC(19177) Eden regions: 72->0(72)
[2026-10-12T14:02:38.610+0800][14912][gc,heap ] GC(19177) Survivor regions: 4->4(10)
[2026-10-12T14:02:38.610+0800][14912][gc,heap ] GC(19177) Old regions: 473->319
[2026-10-12T14:02:38.610+0800][14912][gc,metaspace] GC(19177) Metaspace: 161176K(177216K)->161176K(177216K)
[2026-10-12T14:02:38.610+0800][14912][gc ] GC(19177) Pause Young (Mixed) (G1 Evacuation Pause) 4392M->2584M(12288M) 9.828ms
[2026-10-12T14:02:45.123+0800][14912][gc,start ] GC(19178) Pause Young (Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:45.131+0800][14912][gc,heap ] GC(19178) Eden regions: 72->0(72)
[2026-10-12T14:02:45.131+0800][14912][gc,heap ] GC(19178) Survivor regions: 4->4(10)
[2026-10-12T14:02:45.131+0800][14912][gc,heap ] GC(19178) Old regions: 319->165
[2026-10-12T14:02:45.131+0800][14912][gc,metaspace] GC(19178) Metaspace: 161176K(177216K)->161176K(177216K)
[2026-10-12T14:02:45.131+0800][14912][gc ] GC(19178) Pause Young (Mixed) (G1 Evacuation Pause) 3160M->1351M(12288M) 8.603ms
[2026-10-12T14:02:50.500+0800][14912][gc,start ] GC(19179) Pause Young (Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:50.512+0800][14912][gc,heap ] GC(19179) Eden regions: 72->0(916)
[2026-10-12T14:02:50.512+0800][14912][gc,heap ] GC(19179) Survivor regions: 4->5(10)
[2026-10-12T14:02:50.512+0800][14912][gc,heap ] GC(19179) Old regions: 165->93
[2026-10-12T14:02:50.512+0800][14912][gc,metaspace] GC(19179) Metaspace: 161192K(177216K)->161192K(177216K)
[2026-10-12T14:02:50.512+0800][14912][gc ] GC(19179) Pause Young (Mixed) (G1 Evacuation Pause) 1927M->789M(12288M) 12.135ms
[2026-10-12T14:04:12.366+0800][14912][gc,start ] GC(19180) Pause Young (Normal) (G1 Evacuation Pause)
[2026-10-12T14:04:12.381+0800][14912][gc,heap ] GC(19180) Eden regions: 916->0(917)
[2026-10-12T14:04:12.381+0800][14912][gc,heap ] GC(19180) Survivor regions: 5->4(116)
[2026-10-12T14:04:12.381+0800][14912][gc,heap ] GC(19180) Old regions: 93->93
[2026-10-12T14:04:12.381+0800][14912][gc,metaspace] GC(19180) Metaspace: 161229K(177216K)->161229K(177216K)
[2026-10-12T14:04:12.381+0800][14912][gc ] GC(19180) Pause Young (Normal) (G1 Evacuation Pause) 8117M->779M(12288M) 14.517ms
二、Mixed GC 完整周期解析
阶段 1:触发并发标记(GC 19174)
[2026-10-12T14:01:24.881+0800][14912][gc] GC(19174) Pause Young (Concurrent Start) (G1 Evacuation Pause) 10927M->5557M(12288M) 15.951ms
关键点:
- GC 类型 :
Pause Young (Concurrent Start)- 年轻代回收,同时启动并发标记 - 触发原因:老年代使用率达到 IHOP 阈值(45%)
- 堆变化:10927MB → 5557MB(回收 5370MB)
- 停顿时间:15.951ms
计算老年代使用率:
堆总量:12288MB(12GB)
GC 后堆使用:5557MB
老年代占用(估算):5557MB × 80% ≈ 4446MB
老年代使用率:4446 / 12288 ≈ 36%
但实际触发阈值是 45%,说明在 GC 前老年代已经超过 45%
为什么叫 "Concurrent Start"?
- 这次 Young GC 不仅回收年轻代
- 还启动了并发标记周期(Concurrent Mark Cycle)
- 为后续的 Mixed GC 做准备
阶段 2:并发标记周期(GC 19175)
[2026-10-12T14:01:24.881+0800][14908][gc] GC(19175) Concurrent Mark Cycle
这是一个完整的并发标记周期,包含多个子阶段:
2.1 清理已声明标记
[2026-10-12T14:01:24.883+0800][14908][gc,marking] GC(19175) Concurrent Clear Claimed Marks
[2026-10-12T14:01:24.884+0800][14908][gc,marking] GC(19175) Concurrent Clear Claimed Marks 3.236ms
作用 :清理上一次标记的残留数据
耗时 :3.236ms
特点:并发执行,不停顿应用
2.2 扫描根区域
[2026-10-12T14:01:24.884+0800][14908][gc,marking] GC(19175) Concurrent Scan Root Regions
[2026-10-12T14:01:24.892+0800][14908][gc,marking] GC(19175) Concurrent Scan Root Regions 8.036ms
作用 :扫描 GC Roots(静态变量、栈帧、寄存器等)
耗时 :8.036ms
特点:并发执行,不停顿应用
2.3 并发标记
[2026-10-12T14:01:24.892+0800][14908][gc,marking] GC(19175) Concurrent Mark
[2026-10-12T14:01:24.892+0800][14908][gc,marking] GC(19175) Concurrent Mark From Roots
[2026-10-12T14:01:24.892+0800][14908][gc,task] GC(19175) Using 2 workers of 2 for marking
[2026-10-12T14:01:25.070+0800][14908][gc,marking] GC(19175) Concurrent Mark From Roots 177.877ms
作用 :从 GC Roots 开始,标记所有存活对象
工作线程 :2 个并发标记线程
耗时 :177.877ms
特点:
- 并发执行,应用线程继续运行
- 使用写屏障(Write Barrier)记录对象引用变化
- 这是最耗时的阶段
2.4 并发预清理
[2026-10-12T14:01:25.070+0800][14908][gc,marking] GC(19175) Concurrent Preclean
[2026-10-12T14:01:25.072+0800][14908][gc,marking] GC(19175) Concurrent Preclean 2.111ms
作用 :处理并发标记期间应用线程产生的引用变化
耗时 :2.111ms
特点:减少后续 Remark 阶段的工作量
2.5 重新标记(停顿)
[2026-10-12T14:01:25.073+0800][14912][gc,start] GC(19175) Pause Remark
[2026-10-12T14:01:25.196+0800][14912][gc] GC(19175) Pause Remark 5578M->3834M(12288M) 123.072ms
作用:
- Stop-The-World 停顿
- 处理并发标记期间遗漏的对象
- 完成最终标记
堆变化 :5578MB → 3834MB(回收 1744MB)
停顿时间:123.072ms(较长)
为什么停顿这么长?
- 需要扫描整个堆,确保所有存活对象都被标记
- 处理写屏障记录的引用变化
- 这是 Mixed GC 周期中最长的停顿
2.6 并发重建 Remembered Sets
[2026-10-12T14:01:25.196+0800][14908][gc,marking] GC(19175) Concurrent Rebuild Remembered Sets
[2026-10-12T14:01:25.360+0800][14908][gc,marking] GC(19175) Concurrent Rebuild Remembered Sets 164.177ms
作用 :重建 Remembered Sets(记录跨 Region 引用)
耗时 :164.177ms
特点:并发执行,为 Mixed GC 做准备
2.7 清理停顿
[2026-10-12T14:01:25.360+0800][14912][gc,start] GC(19175) Pause Cleanup
[2026-10-12T14:01:25.361+0800][14912][gc] GC(19175) Pause Cleanup 3874M->3874M(12288M) 0.599ms
作用:
- Stop-The-World 停顿
- 统计每个 Region 的存活对象数量
- 计算回收价值(Garbage First 算法核心)
- 选择回收价值最高的 Region 进行 Mixed GC
堆变化 :3874MB → 3874MB(无变化)
停顿时间:0.599ms(很短)
为什么堆没变化?
- 这个阶段只是统计和计算,不实际回收内存
- 为后续的 Mixed GC 选择目标 Region
2.8 并发清理
[2026-10-12T14:01:25.361+0800][14908][gc,marking] GC(19175) Concurrent Cleanup for Next Mark
[2026-10-12T14:01:25.413+0800][14908][gc,marking] GC(19175) Concurrent Cleanup for Next Mark 51.329ms
[2026-10-12T14:01:25.413+0800][14908][gc] GC(19175) Concurrent Mark Cycle 531.694ms
作用 :清理标记数据结构,为下一次标记做准备
耗时 :51.329ms
总耗时:531.694ms(整个并发标记周期)
阶段 3:准备 Mixed GC(GC 19176)
[2026-10-12T14:02:32.477+0800][14912][gc,start] GC(19176) Pause Young (Prepare Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:32.490+0800][14912][gc,heap] GC(19176) Eden regions: 671->0(72)
[2026-10-12T14:02:32.490+0800][14912][gc,heap] GC(19176) Survivor regions: 4->4(85)
[2026-10-12T14:02:32.490+0800][14912][gc,heap] GC(19176) Old regions: 473->473
[2026-10-12T14:02:32.490+0800][14912][gc,metaspace] GC(19176) Metaspace: 161176K(177216K)->161176K(177216K)
[2026-10-12T14:02:32.490+0800][14912][gc] GC(19176) Pause Young (Prepare Mixed) (G1 Evacuation Pause) 9181M->3816M(12288M) 13.650ms
关键点:
- GC 类型 :
Pause Young (Prepare Mixed)- 年轻代回收,为 Mixed GC 做准备 - Eden 区:671 → 0(清空)
- Survivor 区:4 → 4(不变)
- 老年代:473 → 473(不变,还没开始回收)
- 堆变化:9181MB → 3816MB(回收 5365MB)
- 停顿时间:13.650ms
为什么叫 "Prepare Mixed"?
- 这次 Young GC 是 Mixed GC 前的最后一次纯年轻代回收
- 回收年轻代,为 Mixed GC 腾出空间
- 下一次 GC 将开始回收老年代
老年代占用:
473 regions × 8MB/region = 3784MB
阶段 4:第一次 Mixed GC(GC 19177)
[2026-10-12T14:02:38.600+0800][14912][gc,start] GC(19177) Pause Young (Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:38.610+0800][14912][gc,heap] GC(19177) Eden regions: 72->0(72)
[2026-10-12T14:02:38.610+0800][14912][gc,heap] GC(19177) Survivor regions: 4->4(10)
[2026-10-12T14:02:38.610+0800][14912][gc,heap] GC(19177) Old regions: 473->319
[2026-10-12T14:02:38.610+0800][14912][gc,metaspace] GC(19177) Metaspace: 161176K(177216K)->161176K(177216K)
[2026-10-12T14:02:38.610+0800][14912][gc] GC(19177) Pause Young (Mixed) (G1 Evacuation Pause) 4392M->2584M(12288M) 9.828ms
关键点:
- GC 类型 :
Pause Young (Mixed)- 混合回收(年轻代 + 部分老年代) - Eden 区:72 → 0(清空)
- Survivor 区:4 → 4(不变)
- 老年代 :473 → 319(回收 154 个 Region)
- 堆变化:4392MB → 2584MB(回收 1808MB)
- 停顿时间:9.828ms(很短!)
老年代回收详情:
回收前:473 regions × 8MB = 3784MB
回收后:319 regions × 8MB = 2552MB
回收量:154 regions × 8MB = 1232MB
回收率:1232 / 3784 = 32.6%
为什么停顿时间这么短?
- G1 只选择回收价值最高的部分 Region
- 不是回收整个老年代,而是"混合"回收
- 通过并发标记已经知道哪些 Region 垃圾最多
Metaspace 变化:
161176K → 161176K(无变化)
说明 Mixed GC 没有触发类卸载。
阶段 5:第二次 Mixed GC(GC 19178)
[2026-10-12T14:02:45.123+0800][14912][gc,start] GC(19178) Pause Young (Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:45.131+0800][14912][gc,heap] GC(19178) Eden regions: 72->0(72)
[2026-10-12T14:02:45.131+0800][14912][gc,heap] GC(19178) Survivor regions: 4->4(10)
[2026-10-12T14:02:45.131+0800][14912][gc,heap] GC(19178) Old regions: 319->165
[2026-10-12T14:02:45.131+0800][14912][gc,metaspace] GC(19178) Metaspace: 161176K(177216K)->161176K(177216K)
[2026-10-12T14:02:45.131+0800][14912][gc] GC(19178) Pause Young (Mixed) (G1 Evacuation Pause) 3160M->1351M(12288M) 8.603ms
关键点:
- 老年代 :319 → 165(回收 154 个 Region)
- 堆变化:3160MB → 1351MB(回收 1809MB)
- 停顿时间:8.603ms
老年代回收详情:
回收前:319 regions × 8MB = 2552MB
回收后:165 regions × 8MB = 1320MB
回收量:154 regions × 8MB = 1232MB
回收率:1232 / 2552 = 48.3%
观察:
- 回收的 Region 数量相同(154 个)
- 但回收率更高(48.3% vs 32.6%)
- 说明 G1 选择了垃圾更多的 Region
阶段 6:第三次 Mixed GC(GC 19179)
[2026-10-12T14:02:50.500+0800][14912][gc,start] GC(19179) Pause Young (Mixed) (G1 Evacuation Pause)
[2026-10-12T14:02:50.512+0800][14912][gc,heap] GC(19179) Eden regions: 72->0(916)
[2026-10-12T14:02:50.512+0800][14912][gc,heap] GC(19179) Survivor regions: 4->5(10)
[2026-10-12T14:02:50.512+0800][14912][gc,heap] GC(19179) Old regions: 165->93
[2026-10-12T14:02:50.512+0800][14912][gc,metaspace] GC(19179) Metaspace: 161192K(177216K)->161192K(177216K)
[2026-10-12T14:02:50.512+0800][14912][gc] GC(19179) Pause Young (Mixed) (G1 Evacuation Pause) 1927M->789M(12288M) 12.135ms
关键点:
- 老年代 :165 → 93(回收 72 个 Region)
- Eden 区:72 → 0(916)(注意括号里的 916,表示 Eden 容量扩大到 916)
- 堆变化:1927MB → 789MB(回收 1138MB)
- 停顿时间:12.135ms
老年代回收详情:
回收前:165 regions × 8MB = 1320MB
回收后:93 regions × 8MB = 744MB
回收量:72 regions × 8MB = 576MB
回收率:576 / 1320 = 43.6%
为什么回收的 Region 数量减少了?
- 第一次:154 个
- 第二次:154 个
- 第三次:72 个
原因:
- G1 已经回收了大部分高价值 Region
- 剩余的 Region 垃圾较少,回收价值低
- G1 选择停止 Mixed GC,回到正常 Young GC
Eden 容量变化:
之前:72 regions
之后:916 regions(扩大 12.7 倍)
为什么 Eden 扩大?
- 老年代回收后,堆空间充足
- G1 自适应调整 Eden 大小
- 减少 Young GC 频率
阶段 7:恢复正常 Young GC(GC 19180)
[2026-10-12T14:04:12.366+0800][14912][gc,start] GC(19180) Pause Young (Normal) (G1 Evacuation Pause)
[2026-10-12T14:04:12.381+0800][14912][gc,heap] GC(19180) Eden regions: 916->0(917)
[2026-10-12T14:04:12.381+0800][14912][gc,heap] GC(19180) Survivor regions: 5->4(116)
[2026-10-12T14:04:12.381+0800][14912][gc,heap] GC(19180) Old regions: 93->93
[2026-10-12T14:04:12.381+0800][14912][gc,metaspace] GC(19180) Metaspace: 161229K(177216K)->161229K(177216K)
[2026-10-12T14:04:12.381+0800][14912][gc] GC(19180) Pause Young (Normal) (G1 Evacuation Pause) 8117M->779M(12288M) 14.517ms
关键点:
- GC 类型 :
Pause Young (Normal)- 恢复正常年轻代回收 - 老年代:93 → 93(不变,Mixed GC 结束)
- 堆变化:8117MB → 779MB(回收 7338MB)
- 停顿时间:14.517ms
观察:
- Mixed GC 周期结束
- 回到正常的 Young GC 模式
- 老年代稳定在 93 regions(744MB)
- 堆使用后残留从 5557MB 降到 779MB(大幅下降)
三、Mixed GC 周期总结
时间线
14:01:24.881 GC(19174) Young GC (Concurrent Start) → 触发并发标记
14:01:24.881 GC(19175) Concurrent Mark Cycle → 并发标记开始
14:01:25.413 GC(19175) Concurrent Mark Cycle 结束 → 耗时 531.694ms
14:02:32.477 GC(19176) Young GC (Prepare Mixed) → 准备 Mixed GC
14:02:38.600 GC(19177) Mixed GC (第 1 次) → 回收 1232MB
14:02:45.123 GC(19178) Mixed GC (第 2 次) → 回收 1232MB
14:02:50.500 GC(19179) Mixed GC (第 3 次) → 回收 576MB
14:04:12.366 GC(19180) Young GC (Normal) → 恢复正常
总耗时:约 2 分 48 秒(从触发到结束)
老年代变化
| 阶段 | Old Regions | 占用空间 | 变化 |
|---|---|---|---|
| GC 19176(准备) | 473 | 3784 MB | - |
| GC 19177(第 1 次) | 319 | 2552 MB | -1232 MB |
| GC 19178(第 2 次) | 165 | 1320 MB | -1232 MB |
| GC 19179(第 3 次) | 93 | 744 MB | -576 MB |
| GC 19180(恢复) | 93 | 744 MB | 0 MB |
总回收 :3784MB - 744MB = 3040MB(约 3GB)
回收率 :3040 / 3784 = 80.3%
停顿时间统计
| GC 编号 | 类型 | 停顿时间 |
|---|---|---|
| GC 19174 | Young (Concurrent Start) | 15.951ms |
| GC 19175 | Remark | 123.072ms |
| GC 19175 | Cleanup | 0.599ms |
| GC 19176 | Young (Prepare Mixed) | 13.650ms |
| GC 19177 | Mixed | 9.828ms |
| GC 19178 | Mixed | 8.603ms |
| GC 19179 | Mixed | 12.135ms |
| GC 19180 | Young (Normal) | 14.517ms |
总停顿时间 :198.355ms
最长停顿 :123.072ms(Remark 阶段)
平均停顿:24.794ms
Metaspace 变化
GC 19176: 161176K (157MB)
GC 19177: 161176K (157MB) ← 无变化
GC 19178: 161176K (157MB) ← 无变化
GC 19179: 161192K (157MB) ← 微小变化(+16KB)
GC 19180: 161229K (157MB) ← 微小变化(+37KB)
结论:Mixed GC 没有触发类卸载,Metaspace 基本不变。
四、关键观察
1. Mixed GC 非常高效
- 回收率 80.3%:老年代从 3784MB 降到 744MB
- 停顿时间短:每次 Mixed GC 只有 8-12ms
- 分批次回收:3 次 Mixed GC,每次回收部分 Region
2. G1 的智能选择
- Garbage First 算法:优先回收垃圾最多的 Region
- 第一次:回收 154 个 Region(32.6%)
- 第二次:回收 154 个 Region(48.3%)← 回收率更高
- 第三次:回收 72 个 Region(43.6%)← 数量减少
说明:G1 动态调整回收策略,选择最优的 Region。
3. 并发标记是关键
- 耗时 531.694ms,但大部分时间应用继续运行
- 只有 Remark(123ms)和 Cleanup(0.6ms)需要停顿
- 为 Mixed GC 提供了准确的存活对象信息
4. 自适应调整
- Mixed GC 后,Eden 从 72 regions 扩大到 916 regions
- G1 根据堆使用情况自动调整年轻代大小
- 减少 Young GC 频率,提高吞吐量
五、与第一个日志对比
| 指标 | 第一个日志(异常) | 第二个日志(健康) |
|---|---|---|
| Mixed GC 次数 | 0 次 | 6 次 |
| 老年代回收 | 从未回收 | 回收 3040MB(80.3%) |
| 停顿时间 | - | 8-12ms(很短) |
| Metaspace 回收 | 从未回收 | 微小变化(+53KB) |
| 健康状态 | ❌ 异常 | ✅ 健康 |
关键区别:
- 第一个日志:堆小(6GB),老年代未达 45% 阈值,Mixed GC 未触发
- 第二个日志:堆大(12GB),老年代达到 45% 阈值,Mixed GC 正常触发并有效回收
六、总结
Mixed GC 的完整流程
1. 老年代达到 IHOP 阈值(45%)
↓
2. 触发 Young GC (Concurrent Start)
↓
3. 启动并发标记周期(531ms)
- 并发清理、扫描、标记、预清理
- Remark 停顿(123ms)
- 并发重建 Remembered Sets
- Cleanup 停顿(0.6ms)
↓
4. Young GC (Prepare Mixed)
↓
5. 多次 Mixed GC(每次 8-12ms)
- 回收年轻代 + 部分老年代
- 优先回收垃圾最多的 Region
↓
6. 恢复正常 Young GC
Mixed GC 的优势
- 高效回收:回收率 80.3%,释放 3GB 内存
- 停顿短:每次只有 8-12ms,对应用影响小
- 智能选择:Garbage First 算法,优先回收高价值 Region
- 自适应:根据堆使用情况自动调整策略
为什么第一个日志没有触发 Mixed GC?
第一个日志:
- 堆:6GB
- 老年代:2348MB
- 使用率:38%
- IHOP:45%
- 38% < 45% → 未触发
第二个日志:
- 堆:12GB
- 老年代峰值:5528MB
- 使用率:45%
- IHOP:45%
- 45% = 45% → 触发
结论:堆大小决定了 Mixed GC 的触发时机。堆越小,越早触发;堆越大,越晚触发。