V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
weiwenhao
V2EX  ›  Go 编程语言

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

  •  
  •   weiwenhao ·
    weiwenhao · 2023-09-19 16:50:55 +08:00 · 1759 次点击
    这是一个创建于 429 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我正在实现一个并发的三色标记垃圾收集器,我看了一些帖子,里面描述的 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 还读不到么 🤔.
    5 条回复    2023-09-19 18:05:07 +08:00
    zmcity
        1
    zmcity  
       2023-09-19 17:11:27 +08:00
    提高 gc 吞吐量。
    hankai17
        2
    hankai17  
       2023-09-19 17:15:45 +08:00
    有种 atomic 的感觉
    weiwenhao
        3
    weiwenhao  
    OP
       2023-09-19 17:57:48 +08:00
    @hankai17 原则上可能是为了避免多线程竞争。
    waiY
        4
    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
        5
    gav1nvv  
       2023-09-19 18:05:07 +08:00
    貌似和多线程引用计数需要记录指针调用,如果线程运行中启动,可能会影响指针记录,造成内存泄漏,所以等 goroutine 结束再启动
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2944 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 00:34 · PVG 08:34 · LAX 16:34 · JFK 19:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.