STW是JVM暂停所有应用线程的机制,监控重点在于其频次、时长、分布及与业务延迟的耦合关系;需结合GC日志、业务打点、jstack等定位真实根因。

STW(Stop-The-World)本身不是变量,而是JVM执行关键操作时强制暂停所有应用线程的机制。所谓“变量处理对业务系统的实时冲击”,实际是指:在STW发生期间,因对象分配、引用变更、GC触发条件变化等运行时行为,间接放大或暴露了系统对停顿的敏感性。监控重点不在“变量”本身,而在STW事件的频次、时长、分布及其与业务指标的耦合关系。
看懂STW日志里的关键信号
启用详细GC日志(如 -Xlog:gc*,gc+pause=info),重点关注三类字段:
- Pause Time:每次STW的实际毫秒数,不是平均值,而是每条记录的精确耗时
- Trigger:标明是Young GC、Mixed GC、Full GC,还是System.gc()、元空间扩容等非GC类STW
- Heap Usage Before/After:对比回收前后各代使用量,判断是否因对象晋升过快、大对象直接入老年代等“变量级行为”诱发频繁Mixed或Full GC
把STW和业务延迟对齐验证
单纯看GC日志无法确认是否影响业务,必须叠加业务侧时间戳:
- 在API网关或核心服务入口打点,记录请求进入时间、离开时间、是否落在某次GC pause窗口内
- 用Prometheus + Grafana绘制「GC pause time」与「P95响应延迟」的双Y轴折线图,观察是否存在强时间重叠
- 若某次STW为120ms,而同期有大量请求延迟跳升至200–300ms,说明该次停顿已传导至用户侧
识别由代码逻辑放大的STW风险
某些看似普通的变量操作,会在特定条件下显著拉长STW或提高其发生概率:
- 频繁创建短生命周期大对象(如byte[]、StringBuilder),导致Eden区快速填满,Young GC间隔从秒级缩至百毫秒级
- 静态集合类(如static Map)无节制put,引发元空间(Metaspace)持续增长,最终触发元空间GC——这类STW不显现在常规GC日志里,需加
-Xlog:metaspace*单独捕获 - 使用
ThreadLocal存储大对象且未及时remove,导致GC时扫描更多引用链,延长标记阶段耗时
用jstack辅助定位“伪STW”干扰项
有时业务线程卡在锁、IO或外部调用上,被误判为STW影响。可通过以下方式排除:
- 在GC pause高发时段执行
jstack -l,检查是否有大量线程处于BLOCKED或WAITING状态,而非全部统一停在VM Thread附近 - 比对
jstat -gc中FGC次数与jstack中full gc相关堆栈出现频次,若前者远高于后者,说明存在非JVM主动触发的长时间停顿 - 关注
java.lang.ref.Reference$ReferenceHandler等后台线程是否长期RUNNABLE,可能因软/弱引用队列积压拖慢Reference处理,间接延长STW准备阶段










