运行时核心
调度器
- paper/work-steal Robert D. Blumofe 和 Charles E. Leiserson,通过工作窃取调度多线程计算。J. ACM 46, 5 (September 1999), 720-748.
- cl/sched-m-1 Russ Cox,清理调度器,2008年8月5日。
- cl/sched-m-n 现在情况好多了。2009年11月11日。
- design/go11sched Dmitry Vyukov,可伸缩的 Go 调度器设计文档。2012年
- cl/7314062 运行时:提升的调度器。
- design/sched-preempt-dmitry Dmitry Vyukov。Go 优先权调度器设计文档。2013年
- design/sched-numa Dmitry Vyukov,Go 的 NUMA 感知调度器。2014年9月。
- design/go15gomaxprocs Russ Cox,Go 1.5 的 GOMAXPROCS 默认值。2015年5月。
- doc/go17sched Ian Lance Taylor,Go 调度器怎样工作?2016年7月16日。
- design/sched-preempt-austin Austin Clements,提案:goroutine 抢占竞争。
- cl/43050 cmd/compile:在 amd64 上使用错误分支的循环抢占。
- issue/10958 运行时:紧密循环应该是可抢占的。
- issue/24543 运行时:goroutine 抢占竞争。
- issue/36365 运行时:清理松散结尾上的异步抢占
- issue/14592 运行时:让空闲的系统线程退出。
- issue/18237 运行时:当 goroutine 被经常唤醒时调度很慢。
- issue/20395 运行时:当所属的 goroutine 退出时中断锁住的系统线程。
- issue/20458 提案:运行时:一起调用 LockOSThread、UnlockOSThread
- issue/21827 运行时:使用 runtime.LockOSThread 会造成很大的性能影响。
- issue/27345 运行时:将父 goroutine 的堆栈用于新的 goroutine。
- issue/28808 运行时:当 GOMAXPROCS 很高时调度器工作窃取很慢。
- issue/32113 运行时:减少P流失的优化。
- issue/44313 运行时:已停止的Ms不能成为专用或小数的GC工作者。
- discuss/periodic-task-when-time time.Ticker 和 time.Sleep 开销很大时,如何执行周期任务(golang-nuts)
- discuss/why-there-is-a 为什么 LockOSThread 与通道一起使用时,性能损失如此之大?(golang-nuts)
- design/mutex-spinbit Rhys Hiltner,提案:提高 runtime.lock2 的可扩展性。2024年10月16日。
- issue/61015 运行时:将互斥锁剖析改为按被阻塞的 goroutine 数量缩放争用
- discuss/runtime-setting-gomaxprocs-in 运行时:在过度调度的容器环境中设置 GOMAXPROCS(golang-nuts)
- discuss/concurrency-and-task-scheduler 并发与任务调度器的可扩展性(golang-nuts)
- issue/69687 testing/synctest:用于测试并发代码的实验性包
- issue/45435 sync:添加 Mutex.TryLock
- issue/63796 sync:添加 WaitGroup.Go
- issue/61696 sync:添加 Map.Clear 方法
- design/goroutine-leak-detection-gc Georgian-Vlad Saioc、Milind Chabbi,提案:通过垃圾收集检测 goroutine 泄漏。2025年8月14日。
- issue/74609 runtime/pprof,运行时:新的 goroutine 泄漏剖析
- issue/38651 运行时:在栈跟踪中加入“created by goroutine 编号”
- issue/543 运行时:抢占式调度
- issue/68578 运行时:改进 lock2 的可扩展性
- issue/66999 运行时:正确归因运行时内部的互斥锁争用
- issue/57071 runtime/metrics:提供度量运行时内部锁争用的方法
- issue/49881 runtime/metrics:添加争用指标
- issue/81657 运行时:加速 GC 阶段转换
- issue/65694 运行时:加强 G ↔ P ↔ M ↔ CPU 之间的亲和性?
- issue/53789 运行时:仿照 go/build/deps_test.go,将锁等级图表示为 DAG
- issue/13759 提案:为 Go 添加部分死锁检测器
- issue/21678 运行时:为调试器提供在被调试程序中执行函数的机制
- issue/70089 提案:runtime/mainthread:添加 mainthread.Do,用于协调对主线程的访问
- doc/container-aware-gomaxprocs Michael Pratt、Carlos Amedee,感知容器的 GOMAXPROCS。2025年8月20日。
执行栈
- design/contigstack 连续堆栈
- issue/17007 运行时:致命错误:就绪状态糟糕的 g->status
- issue/18138 运行时:新的 goroutine 在更多堆栈上花费更多的时间
- design/predict-stack-size Keith Randall,确定一个好的堆栈起始大小,2021年8月18日。
- cl/341990 运行时:预测堆栈大小
- cl/345889 运行时:测量堆栈使用情况;需要的话就启动更大的堆栈
- issue/26061 运行时:g0 stack.lo 有时太慢
- discuss/proposal-shared-libraries-in 提案:Go 中的共享库,第二版(附 linux/amd64 实现)(golang-nuts)
- discuss/re-patch-rfc-go Re: [PATCH] RFC:Go 共享库支持(Linux/x64)(golang-nuts)
- issue/15403 internal/cpu:暴露处理器能力的新包
- issue/27218 运行时:在 GODEBUG 中记录(并支持)cpu 选项
- issue/30439 所有:移除 nacl 移植
- issue/21865 runtime/secret:添加新包
- issue/66450 crypto/subtle:添加 WithDataIndependentTiming
- issue/45453 所有:添加 GOAMD64 环境变量
- issue/60905 所有:添加 GOARM64=v8.1 等取值
- issue/36435 所有:在 OpenBSD 上停止使用非 libc 的系统调用
- issue/17490 cmd/link:在 macOS 上通过 libsystem_kernel.dylib 或 libSystem.dylib 进行系统调用
- issue/58378 运行时:支持使用帧指针展开跨 cgo 的逻辑栈切换
- issue/16638 运行时:使用帧指针获取调用者
- issue/69577 crypto/rand:使用 Linux 新的 vDSO
内存分配器
Go 内存分配的实力简述:Russ Cox 在 Go 1 上首次实现了基于 tcmallor 的内存分配器,mcache 缓存在 M 上。然后他修改了分配器,允许使用 16GB 的内存,后来到了128GB。然而,分配器(包括收集器)有很严重的锁竞争,且不可伸缩。在 Dmitry 的可伸缩运行时调度器后,分配器可以直接从P锁竞争中分配(更少)。同时,收集器从独立线程迁移到系统监视器线程。现在,Michael 正致力于提高内存分配器的可伸缩性,例如将收集器迁移到用户线程,基于位图的页分配器,可伸缩的 mcentral。
- doc/tcmalloc Sanjay Ghemawat, Paul Menage。TCMalloc : 线程缓存 Malloc,谷歌,2009。
- design/go113scavenge Michael Knyszek,提案:智能收集。2019年5月9日。
- issue/30333 运行时:智能收集
- issue/32012 运行时:后台收集对小堆过于频繁
- issue/31966 运行时:后台收集堆栈会显著延迟死锁检测
- issue/34047 运行时:由 scavenge.lock 引起的潜在死循环
- issue/34048 运行时:收集器步长无法解释碎片
- issue/35788 运行时:收集器的效率低于之前
- issue/36521 运行时:Go 1.12 性能下降
- issue/36603 运行时:系统经常在不收集的内存上调用
- design/go114pagealloc Michael Knyszek, Austin Clements,提案:缩放Go 页分配器。2019年10月18日。
- issue/35112 运行时:页分配器缩放
- cl/200439 运行时:对触发比例设置下限
- issue/8885 运行时:考虑添加24字节大小的类
- issue/37487 运行时:提高 mcentral 的可扩展性
- cl/221182 运行时:添加新的 mcentral 实现
- issue/18155 运行时:当没有垃圾时延迟扫描辅助
- issue/19112 运行时:gcControllerState.enlistWorker 死锁
- issue/23687 运行时:在 Linux 上也使用 MADV_FREE
- cl/135395 运行时:在 Linux 上使用 MADV_FREE(如果可用)
- issue/29707 cmd/trace: 无法解析轨迹:无法对事件进行一致的排序
- issue/35954 运行时:句柄更优雅地分配到分配器地址空间的顶部
- issue/37927 运行时:GC 步长在低 GOGC 表现出奇怪行为。
- issue/38130 运行时:页分配器的健全性检查不正确。
- issue/38404 运行时:在 arm64/mips64le 上,STW GC 不工作。
- issue/38605 运行时:pageAlloc.allocToCache 不正确地更新 pageAlloc.searchAddr
- issue/38617 运行时:Go 1.14 中收集器在 Windows 里冻结,因为时间粒度太粗略。
- issue/38966 运行时:aix-ppc64 构建器出现致命错误:“修剪错误”,“地址范围的基准和限制不在同一个内存片段中”
- issue/39128 运行时:从 CL 233497 开始,linux-mips-rtrk 构建器一直因为“修剪错误”而失败。
- issue/40191 运行时:pageAlloc.searchAddr 可能指向不连续堆中的未映射的内存,违反了其不变性
- issue/40457 运行时:runqputbatch 不保护它对 globrunqputbatch 的调用。
- issue/40641 运行时:堆栈收缩和通道收发之前的竞争导致错误的 sudog 值
- issue/42330 运行时:在 Linux 上默认为 MADV_DONTNEED
- cl/267100 运行时:在 Linux 上默认为 MADV_DONTNEED
- design/scaling-the-page-allocator Michael Knyszek、Austin Clements,提案:扩展 Go 页分配器。2019年10月18日。
- design/smarter-scavenging Michael Knyszek,提案:更智能的内存归还(scavenging)。
- design/heap-hugepage-util Michael Knyszek、Michael Pratt,更能感知大页的 Go 堆。
- design/memory-regions 内存区域(memory regions)。
- discuss/70257 内存区域(讨论)
- design/runtime-freegc 直接释放用户内存以减少 GC 工作。
- discuss/a-safe-free-of 一个安全释放内存的提案:runtime.FreeMemory()(golang-nuts)
- issue/10460 运行时:512GB 内存限制
- issue/79286 运行时:sizespecializedmalloc 实验
- issue/40431 提案:runtime.Pin(),防范将来可能出现的移动式 GC
- issue/69327 运行时:clear、append、bytes.growSlice 等中的清零不可抢占
- design/go-pmem Jerrin Shaji George、Mohit Verma、Rajesh Venkatasubramanian、Pratap Subrahmanyam,提案:在 Go 中添加对持久内存的支持。2021年1月20日。
- issue/43810 提案:规范:在 Go 中原生支持持久内存编程(已拒绝)
- doc/unique Michael Knyszek,新的 unique 包。2024年8月27日。
- doc/size-specialized-allocations Michael Matloob,按大小特化的内存分配。2026年9月16日。
垃圾收集器
- paper/on-the-fly-gc Edsger W. Dijkstra, Leslie Lamport, A. J. Martin, C. S. Scholten 和 E. F. M. Steffens。动态垃圾收集:合作练习。Commun.ACM 21,11(1978年11月),966-975。
- paper/yuasa-barrier T. Yuasa。通用机器上的实时垃圾收集。J. Syst. Softw. 11,3 (1990年3月),181-198.
- design/go13gc Dmitry Vyukov,更简单和更快速的 Go GC。2014年7月16日。
- cl/106260045 运行时:更简单和更快速的 Go GC
- design/go14gc Richard L. Hudson。Go 1.4+ 的垃圾收集计划和路线图。2014年8月6日。
- design/go15gcpacing Austin Clements。Go 1.5 并发垃圾收集步长。2015年3月10日。
- discuss/gcpacing Austin Clements 等人。关于“提案:垃圾收集器步长”的讨论。2015年3月10日。
- issue/11970 运行时:将 GC 协调器替换为状态机。
- design/sweep-free-alloc Austin Clements。提案:密集标记位和无扫描分配。2015年9月30日。
- issue/12800 运行时:将空间的列表替换为直接的位图分配。
- design/decentralized-gc Austin Clements。提案:分散的GC协调器。2015年10月25日。
- issue/12967 运行时:标记终止时的收缩堆栈显著增加了 GC 的 STW 时间
- issue/14951 运行时:突变的辅助过于激进,尤其是在高 GC 时。
- design/eliminate-rescan Austin Clements, Rick Hudson。消除 STW 堆栈的再次扫描。2016年10月21日。
- issue/17503 运行时:消除堆栈再扫描。
- design/concurrent-rescan Austin Clements, Rick Hudson。提案:堆栈的并发再扫描。2016年10月18日。
- issue/17505 运行时:堆栈并发再扫描。
- design/soft-heap-limit Austin Clements。提案:分开软硬堆大小目标。2018年7月12日。
- issue/22460 运行时:优化写入屏障。
- design/roc 面向请求的收集器算法(ROC)
- cl/roc 运行时:用 ROC 编写屏障代码
- cl/generational-gc 运行时:触发器生成GC
- doc/ismm-gc Rick Hudson,Go 垃圾收集器之旅。
- discuss/ismm-gc 垃圾回收 Slides 和 Transcritp 已可用。
- design/simplify-mark-termination Austin Clements,提案:简略标记终止和消除标记2。2018年8月9日。
- issue/26903 运行时:简略标记终止和消除标记2
- design/gcscan 提案:堆栈的GC扫描
- issue/22350 cmd/compile: 编译器莫名其妙地保留内存。
- issue/27993 运行时:错误消息:在标记终止时 P 会缓存 GC 内容。
- issue/37116 运行时:在 Go1.14rc1 中 GC 会延迟 10ms-26ms,可能因为 GC 空闲。
- issue/42430 运行时:GC 里 pacer 问题讨论
- issue/39983 运行时:空闲的GC妨碍自动缩放
- issue/17969 运行时:侵略型的GC实现会干扰共同租户。
- issue/14812 运行时:GC 导致延迟峰值。
- issue/40460 运行时:goroutine 可能分配超出硬堆目标。
- issue/29696 提案:运行时:为应用增加回应GC反压力的方式。
- issue/23044 提案:运行时:添加一种机制来指定最小目标堆大小
- issue/42642 运行时:多毫秒扫描终止暂停(第二版)
- issue/44163 运行时:删除空闲的GC工作者。
- issue/44167 运行时:重新设计 GC Pacer
- design/gc-pacer-redesign 重新设计 GC Pacer
- issue/44309 提案:runtime/debug: 用户可配置目标内存
- issue/48409 提案:runtime/debug: 软内存限制
- design/user-configurable-memory-target 用户可配置目标内存
- design/soft-memory-limit 软内存限制
- issue/45894 运行时:标记终止重启突变太慢。
- issue/45315 运行时:runtime.GC 无需完成扫描就能返回。
- discuss/sub-millisecond-gc-pauses 亚毫秒级 GC 停顿(golang-dev)
- issue/67535 运行时:添加 AddCleanup
- issue/71825 运行时:允许清理函数并发运行
- issue/67552 weak:提供弱指针的新包
- discuss/secure-go-binaries 安全的 Go 二进制文件(golang-nuts)
- issue/11911 运行时:并发 GC 下堆无限增长
- issue/12041 运行时:重新设计 GC 同步
- issue/27583 运行时:功能请求:支持堆的 ASLR
- doc/go119runtime Michael Knyszek,Go 运行时:四年之后。2022年9月26日。
- doc/cleanups-and-weak Michael Knyszek,从 unique 到 cleanup 与 weak:提升效率的新底层工具。2025年3月6日。
- talk/madhav2022 Madhav Jivrajani,深入控制理论与并发垃圾回收。GopherCon 2022,芝加哥。2022年10月。
- talk/tarun2022 Tarun Pothulapati,Go 1.19 中的软内存限制。闪电演讲,GopherCon 2022,芝加哥。2022年10月。
- talk/yifei2023 Yifei Zhang,Balanced GC:一个用于 Go 的复制式垃圾收集器。GopherCon 2023,圣迭戈。2023年9月。
统计
- issue/16843 运行时:用于监控堆大小的机制
- cl/setmaxheap Austin Clements,runtime/debug:添加 SetMaxHeap 应用接口。2017年6月26日。
- design/go116runtime-metric Michael Knyszek,提案:用于不稳定运行时的指标应用接口。2020年3月18日。
- issue/19812 运行时:在GC期间无法 ReadMemStats。
- issue/38712 运行时:TestMemStats 很奇怪
- issue/40459 运行时:在循环中调用 ReadMemStats 可能阻止GC
- design/go-runtime-stats Go 运行时统计。
- issue/37112 运行时:用于不稳定指标的 API
- issue/47216 runtime/metrics:添加 GOMAXPROCS、NumCgoCall、GC CPU 时间
- issue/56857 runtime/metrics:添加 /gc/heap/live:bytes
- design/memlimits Go 的内存限制(公开版)。在 issue/16843 中提出,
内存模型
Go 内存模型包含以下方面:
- 关于原子操作的内存顺序
- 关于 sync 包应用接口的内存顺序
- 关于运行时机制的内存顺序(即对象终结器)
- doc/refmem Rob Pike 和 Russ Cox。Go 内存模型。2009年2月21日。
- issue/4947 cmd/cc: 原子的实质
- issue/5045 文档:定义 sync/atomic 和内存模型怎样交互
- issue/7948 文档:定义 sync 和内存模型怎样交互
- issue/9442 文档:定义 finalizers 和内存模型怎样交互
- issue/33815 doc/go_mem: "hello, world" 并不总是打印两次
- cl/75130045 文档:允许缓冲通道在未初始化时作为信号量
- doc/gomem Russ Cox。Go 内存模型。2016年2月25日。
- doc/go2017russ Russ Cox,我的Go决议2017:内存模型。2017年1月18日。
- doc/atomic-bug atomic 包
- discuss/atomic-mem-order 通过 atomic 的 Load/Store 来提供内存顺序保证。
- issue/37355 runtime/race: 使用 -race 运行但没有 race(与内存模型不匹配)
- cl/220419 运行时:交换 raceacquire() 和 racerelease 的顺序
- issue/42598 运行时:在 CL 220419 后缓冲通道的明显错误的竞争报告。
- cl/271987 运行时:在调用竞争检测器前检查通道的 elemsize
- [paper/fava2020fix] Fava, Daniel Schnetzer,“查找并修复Go内存模型和数据竞争检测器间的不匹配。”软件工程和格式化方法的国际化会议。2020年 Springer, Cham。
- doc/mm Russ Cox,内存模型,2021年6月
- doc/hwmm Russ Cox,硬件内存模型。2021年6月29日。
- doc/plmm Russ Cox,编程语言内存模型。2021年7月6日。
- doc/gomm Russ Cox,更新Go内存模型。2021年7月12日。
- discuss/47141 更新Go内存模型。
- discuss/align-64-bit-integers 在 32 位平台上对齐 64 位整数(golang-dev)
- issue/61395 sync/atomic:为无符号类型添加 OR/AND 操作
- issue/53821 运行时:将原子值转换为 runtime/internal/atomic 类型
ABI
- design/cgo-pointers Ian Lance Taylor,提案:在Go和C之间传递指针的规则。2015年10月。
- issue/12416 cmd/cgo: 指定Go和C之间传递指针的规则。
- design/internal-abi Austin Clements. 创建未定义的内部调用规定。2019年1月14日。
- issue/27539 提案:运行时:使 ABI 未定义,作为更改的步骤。
- issue/31193 cmd/compile,运行时:减少函数开头的开销。
- design/register-call Austin Clements, 另有 Cherry Zhang, Michael Knyszek, Martin Möhrmann, Michael Pratt, David Chase, Keith Randall, Dan Scales, and Ian Lance Taylor 提供建议。提案:基于注册的Go调用协议。2020年8月10日。
- issue/18597 提案: cmd/compile: 定义基于注册的调用协议。
- issue/40724 提案:Go 函数切换到基于注册的调用协议。
- design/internal-abi-spec Go 内部ABI规范。
- issue/78902 simd:在 GOEXPERIMENT 下提供与架构和向量长度无关的 SIMD 内建函数
- issue/44816 cmd/compile:寄存器 ABI 启动阶段的测试用例失败(跟踪问题)
Misc
- issue/20135 运行时:删除元素时map收缩。
- discuss/design-discuss-switch-hashmap 设计讨论:将哈希表实现切换为 SipHash-2-4(golang-dev)
- issue/14874 提案:cmd/compile:由编译器生成 itab 符号
- issue/61716 math/rand/v2:修订后的 math/rand API
- discuss/60751 math/rand/v2:math/rand 的新 API,也是标准库的第一个 v2 包(讨论)
- issue/16093 runtime/pprof:以 gzip 压缩的 proto 格式生成剖析文件
- issue/76349 运行时:在回溯中加入 runtime/pprof 的 goroutine 标签
- issue/42888 runtime/debug:添加 SetCrashOutput(file *os.File)
- issue/37475 cmd/go:在二进制文件中记录 git/vcs 当前的 HEAD 哈希、提交哈希和 dirty 标志
- issue/67182 runtime/debug:添加 SetCrashOutput 选项
- issue/3885 运行时:分析并调优 map 代码
- issue/25237 运行时:适时轮换 map 的键种子
- issue/2630 运行时:哈希函数应随机化,以防止 DoS 攻击
- issue/20505 运行时:需要更好的 itab 表
- issue/75280 runtime/pprof,运行时:以 GOEXPERIMENT 形式添加新的 goroutine 泄漏剖析
- doc/randv2 Russ Cox,用 math/rand/v2 演进 Go 标准库。2024年5月1日。
- doc/chacha8rand Russ Cox、Filippo Valsorda,Go 1.22 中的安全随机数。2024年5月2日。
- doc/swisstable Michael Pratt,用 Swiss Table 实现更快的 Go map。2025年2月26日。
- doc/goroutine-leak-profiles Vlad Saioc,Goroutine 泄漏分析。2026年9月2日。