golang 的 GC 为什么需要等到所有 goroutine 停止才能够开始?

2023-09-19 16:50:55 +08:00
 weiwenhao
我正在实现一个并发的三色标记垃圾收集器,我看了一些帖子,里面描述的 1.14 之前,golang 无法强制停止 goroutine 从而无法启动开始 gc 。

我的疑问是,全局变量 runtime.writeBarrier 更新了之后,运行中的 goroutine 不就读到了 writeBarrier 并启动了写屏障么,为什么必须等待 goroutine 停止呢?

92 CMPL runtime.writeBarrier(SB), $0
99 JEQ 103
101 JMP 108
108 CALL runtime.gcWriteBarrier(SB)

---

更近一步,假设刚刚更新完读不到,那更新完等个几十 ms 还读不到么 🤔.
1733 次点击
所在节点    Go 编程语言
5 条回复
zmcity
2023-09-19 17:11:27 +08:00
提高 gc 吞吐量。
hankai17
2023-09-19 17:15:45 +08:00
有种 atomic 的感觉
weiwenhao
2023-09-19 17:57:48 +08:00
@hankai17 原则上可能是为了避免多线程竞争。
waiY
2023-09-19 17:59:24 +08:00
[粗线条话 GC (一)] https://www.bilibili.com/video/BV1hv411x7we?p=19
我看这里有简单解释了一下,GC 开始前需要 STW 通知全部的 g 开启写屏障,没有 STW 的话可能会导致部分的 g 开启写屏障有延时导致错误。至于”1.14 之前,golang 无法强制停止 goroutine 从而无法启动开始 gc “是因为 1.13 之前是依赖编译期间插入的代码来检测是否有 gc 在等待执行,如果代码中有个 for{}循环就会导致插入的代码无法执行,从而导致一直阻塞
gav1nvv
2023-09-19 18:05:07 +08:00
貌似和多线程引用计数需要记录指针调用,如果线程运行中启动,可能会影响指针记录,造成内存泄漏,所以等 goroutine 结束再启动

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/975255

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX