GarbageCollectorMXBean.getCollectionTime() 返回JVM启动以来该GC类型所有STW阶段累计耗时(毫秒),仅统计导致应用停顿的阶段,如Serial/Parallel全阶段、CMS的initial mark和remark、G1/ZGC的明确STW子阶段;需两次采样求差计算区间耗时,注意区分GC类型实例。

GarbageCollectorMXBean.getCollectionTime() 返回的是该垃圾收集器自 JVM 启动以来,所有 GC 活动所消耗的累计 STW(Stop-The-World)时间总和,单位为毫秒。
这个值不是单次 GC 的耗时,也不是平均耗时,而是所有该类型 GC 事件中,JVM 实际暂停应用线程、执行回收工作的总时长。
getCollectionTime 统计哪些阶段?
它只统计真正导致应用线程停顿的阶段耗时,具体取决于使用的 GC 算法:
Serial / Parallel / G1(Young GC) / ZGC(部分阶段)等:
整个 GC 过程基本是 STW 的,所以getCollectionTime基本等于所有 Young GC 或 Full GC 的实际暂停时间之和。CMS(Concurrent Mark-Sweep):
getCollectionTime仅包含 initial mark 和 remark 阶段的耗时,不包括 concurrent mark、concurrent sweep 等并发阶段。
因为只有这两个阶段需要全局暂停(STW),其余阶段与用户线程并发运行。G1(Mixed GC)或 Shenandoah / ZGC:
只计入明确 STW 的子阶段(如 G1 的 Evacuation pause、ZGC 的 Pause Mark Start / Pause Relocate),不计入并发标记、并发转移等非阻塞阶段。
使用时要注意的关键点
- 它是单调递增的 long 值,不会重置,需通过两次采样做差值来计算某段时间内的 GC 暂停总耗时。
- 不同 GC 类型对应不同
GarbageCollectorMXBean实例(如G1 Young Generation和G1 Old Generation),要分别调用getCollectionTime()。 - 返回值是“近似值”,JVM 实现可能因精度限制存在几毫秒误差,但对监控和告警足够可靠。
- 如果某 GC 收集器从未触发过,
getCollectionTime()返回 0;若该收集器不支持计时(极罕见),可能返回 -1(文档说明中提及getCollectionCount()有 -1 场景,getCollectionTime()虽未明说,但行为类似)。
怎么用代码算出最近 1 分钟的 GC 暂停耗时?
long prevTime = 0;
// 初始化获取一次
for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
if ("G1 Young Generation".equals(gc.getName())) {
prevTime = gc.getCollectionTime();
break;
}
}
// 等待 60 秒后再次采集
Thread.sleep(60_000);
long currTime = 0;
for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
if ("G1 Young Generation".equals(gc.getName())) {
currTime = gc.getCollectionTime();
break;
}
}
long deltaMs = currTime - prevTime; // 这 60 秒内 Young GC 总 STW 耗时(毫秒)这个 delta 就是你真正关心的“GC 对服务响应的影响时长”。
不复杂但容易忽略

















