Hasty Briefsbeta

双语

A 40ms Go GC pause caused by swap

2 days ago
  • 由于交换区中的元数据页面,Go GC的全局停顿从中位数51微秒增加到40毫秒,导致严重的性能问题。
  • 根本原因是内核将很少访问的页面换出到交换区,包括GC的元数据,这些数据在停顿期间被读取,导致大量缺页错误。
  • 在最严重的停顿中,228次缺页错误占用了40毫秒中的39毫秒,罪魁祸首是GC的簿记操作,如spanSet.reset和finishsweep_m。
  • 该问题在清扫和标记终止阶段都会发生,测试中30分钟内出现了312次此类停顿,凸显了影响的频繁性。
  • 停顿会影响所有goroutine并停止I/O处理,使得40毫秒成为一个关键的延迟问题,尤其是对于生产环境服务。
  • 此外,构建一个511 KiB的消息在NVMe上耗时105毫秒,在网络存储上耗时903毫秒,这是一个仅影响分配goroutine的次要开销。
  • 作者同意Chris Down的观点,即交换区并非邪恶,但警告其与垃圾回收交互不佳,即使使用Go 1.26的Green Tea GC,影响仍然存在。
  • 包括BPF脚本和图表的详细实验已在GitHub上公开,供进一步分析。