initial mark 是 cms/g1 并发 gc 的 stw 起始阶段,日志含时间戳、阶段标识、老年代/全堆占用与容量、stw 耗时;触发于老年代使用率达阈值或预测将超限;单次>50ms或频繁触发需警惕。

初始标记(Initial Mark)是 CMS 和 G1 等并发垃圾收集器的关键阶段,它属于STW(Stop-The-World)事件,必须关注其耗时和触发时机。
怎么看 Initial Mark 这一行日志
典型格式示例:
697.323: [CMS-initial-mark: 302710K(655360K)] 348624K(786368K), 0.1140530 secs拆解关键信息:
- 时间戳:697.323 —— JVM 启动后约 697.3 秒,用于对齐业务监控或延迟尖峰
-
阶段标识:
CMS-initial-mark或G1 Pause (initial-mark),明确表示这是初始标记阶段 - 老年代占用与容量:302710K(655360K) —— 标记开始前,老年代已使用 302.7MB,总容量 640MB
- 整个堆快照:348624K(786368K) —— 此刻堆总使用量 348.6MB,总堆大小 768MB
- STW 耗时:0.1140530 secs ≈ 114ms —— 应用完全暂停时间,直接影响接口 P99 延迟
Initial Mark 的触发条件要结合上下文判断
它不是孤立发生的,而是 CMS 或 G1 并发周期的起点。常见触发原因包括:
-
CMS 场景:老年代使用率接近
-XX:CMSInitiatingOccupancyFraction阈值(默认 92%,但常被调低),或由元空间回收、显式 GC 等间接触发 -
G1 场景:预测下次 Young GC 后老年代占用将超阈值(
InitiatingOccupancyPercent),或混合 GC 需求上升 -
注意区分:CMS-initial-mark 是 STW 阶段;而后续的
CMS-concurrent-mark-start是并发阶段,不暂停应用
重点关注的异常信号
Initial Mark 本身耗时不长(通常几毫秒到几十毫秒),但以下情况需警惕:
- 单次耗时 >50ms:可能因老年代对象过多、GC Roots 太大(如静态集合庞大、线程栈深)、或发生类卸载竞争
- 频繁触发(如每分钟多次):说明老年代增长过快或阈值设得太低,容易引发连续并发周期甚至退化为 Serial Old
- 与 Full GC 紧邻出现:例如 Initial Mark 后很快发生 Concurrent Mode Failure,则表明并发标记跟不上分配速度,系统已承压
如何快速定位和验证
不要只盯这一行,要结合前后日志看完整脉络:
- 往前查:上一次 CMS-initial-mark 是什么时候?间隔是否明显缩短?
- 往后查:是否紧跟着
CMS-concurrent-mark-start?中间有无Concurrent Mode Failure? - 横向比:同一时段内 Young GC 频率是否突增?老年代“回收后占用”是否阶梯式上涨?
- 对齐业务:该时间点是否对应定时任务启动、批量导入、或流量高峰?










