并发标记触发的明确标志是日志中出现“[GC concurrent-mark-start]”,此前需满足堆占用达IHOP阈值(默认45%),且常 preceded by “[GC pause (G1 Evacuation Pause) (young) (initial-mark)”事件。

并发标记(Concurrent Mark)不是独立的 GC 事件,而是 G1 垃圾回收周期中的一个关键阶段,它的启动标志着 Mixed GC 即将开始。识别其触发时机,核心是看日志中是否出现明确的并发标记起始标识,并结合前置条件判断是否满足。
看日志中是否有 “Concurrent Cycle” 或 “Concurrent Mark” 开始标记
当 JVM 启动并发标记周期时,G1 日志会输出类似以下条目:
- [GC concurrent-root-region-scan-start] —— 并发根区域扫描开始(初始化标记后立即触发)
- [GC concurrent-mark-start] —— 并发标记正式开始(真正遍历对象图)
- [GC concurrent-mark-end] —— 并发标记完成
- [GC remark] —— 最终标记(STW 阶段,通常紧接在 concurrent-mark-end 后)
- [GC cleanup] —— 清理阶段(STW,为 Mixed GC 筛选 CSet)
这些条目共同构成一次完整的并发标记周期。只要看到 concurrent-mark-start,就说明并发标记已触发。
确认触发前提:堆占用达 IHOP 阈值
并发标记不会凭空启动,它由堆内存使用率驱动。G1 默认在老年代占用率达到 InitiatingHeapOccupancyPercent(IHOP)= 45% 时启动该周期。
- 可通过 -XX:InitiatingHeapOccupancyPercent=N 调整(例如设为 35 表示更早启动)
- 日志中常伴随提示:[G1Ergonomics (Concurrent Cycles) request concurrent cycle initiation]
- 若应用分配快、晋升多,可能在 Young GC 过程中就检测到达标,于是下一次 GC 就转为并发标记起始阶段
注意初始化标记(Initial Mark)与并发标记的关系
初始化标记是并发标记周期的第一步,但它本身是 STW 的,且和一次 Young GC 合并执行。日志中表现为:
- [GC pause (G1 Evacuation Pause) (young) (initial-mark)]
- 该事件出现,代表并发标记周期已“挂号”,后续很快会进入 concurrent-root-region-scan 和 concurrent-mark
- 所以,initial-mark 日志是并发标记即将开始的最早可靠信号
排除干扰:不是所有 “concurrent” 都指标记
G1 日志中还有其他并发阶段,如:
- [GC concurrent-cleanup-start] —— 属于清理阶段,发生在 remark 之后
- [GC concurrent-string-deduplication] —— 字符串去重,与标记无关
- 仅当看到 concurrent-mark-start 或明确带 Concurrent Mark 字样的条目,才代表标记阶段启动

















