共130行

STW: Go 、Java、Erlang

2026-05-05 01:59:03

Golang STW vs Java STW

Golang STW 整体远短于 Java,且频率更低、影响更小:Go 仅两次微秒级暂停;Java 多数 GC 存在毫秒–秒级暂停,ZGC/Shenandoah 可做到亚毫秒但仍有开销。


一、基本概念


二、Golang STW 机制(Go 1.5+)

1. 触发阶段(仅两次)

  1. Mark Setup(标记启动):开启写屏障、准备根扫描;STW 微秒级(≈10–100μs)
  2. Mark Termination(标记终止):完成最终标记、关闭写屏障;STW 微秒级(≈10–100μs)

2. 关键优化


三、Java STW 机制(主流收集器)

1. 经典收集器(STW 严重)

2. 并发收集器(部分阶段 STW)

3. 低延迟收集器(亚毫秒级 STW)


四、核心对比表

对比维度 Golang(Go 1.5+) Java(主流收集器)
STW 次数 2 次/GC 1–多次/GC(取决于收集器)
单次时长 微秒级(10–100μs) 经典:毫秒–秒级;ZGC/Shenandoah:<1ms
触发阶段 Mark Setup、Mark Termination 初始标记、重新标记、Full GC 全程等
与堆大小关系 无关 强相关(堆越大,STW 越长)
分代 无分代 年轻代+老年代,Full GC 更耗时
写屏障 有(Dijkstra 插入式) 有(不同收集器实现不同)
适用场景 高并发、低延迟(微服务、网关) 企业级应用(需调优 GC)

五、影响与选型建议

  1. Golang 优势:STW 极短,高并发下响应稳定,适合对延迟敏感的服务(如 API 网关、消息队列)。
  2. Java 优势:成熟生态、分代 GC 吞吐高,ZGC/Shenandoah 可满足低延迟需求,适合复杂企业应用。
  3. 选型参考

六、总结

Golang 通过并发三色标记+两次微秒级 STW,将暂停影响降至极低;Java 传统收集器 STW 较重,现代 ZGC/Shenandoah 已接近 Go 水平,但仍有额外开销。理解差异有助于根据业务场景选择合适语言与 GC 策略。

要不要我整理一份 Go 与 Java 的 GC 调优清单(含关键参数、常用工具和典型问题排查步骤)?

Erlang STW

Erlang 无全局STW,只有单进程级STW;粒度最细、全局零暂停、延迟最稳,远优于Go与Java。


一、核心设计:无共享堆,进程独立GC

Erlang VM(BEAM)的核心是每个进程独占私有堆(heap),进程间无共享内存,仅靠消息传递通信。

二、Erlang的“STW”:仅进程级,毫秒内

1. 单进程GC过程(分代拷贝)

每个进程私有堆默认233字(≈2KB),按斐波那契数列扩容;GC为分代拷贝(Generational Copying)

  1. Minor GC(年轻代):仅扫描/复制年轻代,STW≈微秒–亚毫秒
  2. Major GC(全堆):扫描/复制整个进程堆,STW≈1–5ms(堆越大越长,但进程堆通常很小)。

2. 关键:进程级暂停,非全局

三、Go/Java/Erlang STW 对比表

对比维度 Erlang(BEAM) Golang(Go 1.5+) Java(ZGC/Shenandoah)
STW范围 单进程级(无全局STW) 全局(两次微秒级) 全局(亚毫秒级)
STW次数 每进程GC 1次 每GC 2次 每GC 1–多次
单次时长 微秒–5ms(进程堆) 10–100μs <1ms
与堆大小关系 仅与单进程堆相关 无关 弱相关(优化后)
全局抖动 极低 极低
并发模型 Actor模型,无共享 CSP,共享内存 线程,共享内存

四、为什么Erlang几乎无抖动?

  1. 极致隔离:进程私有堆+无共享状态,GC天然隔离,互不影响。
  2. 轻量进程:百万级进程,每个堆极小(KB级),单进程GC极快。
  3. 软实时调度:BEAM调度器按时间片公平调度,GC不阻塞调度器,延迟稳定。
  4. 不可变数据:变量不可变,无写屏障开销,GC逻辑更简单高效。

五、适用场景与局限

优势场景

局限

六、总结