分享
  1. 首页
  2. 文章

go怎样做stw

yixiao · · 3518 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

原文链接: Go: How Does Go Stop the World? : Author : Vincent Blanchon

本文基于 go 1.13

在垃圾回收算法中,Stop The Word(STW)是一个很重要的概念,他会中断程序运行,添加写屏障,以便扫描内存 ,现在一起来看看它内部的原理以及可能存在的问题

STW

停止程序运行意味着停止所有运行态的goroutines,一个简单的例子:

func main() {
runtime.GC()
}

运行垃圾回收算法将触发两个阶段的STW

有关垃圾回收的更多细节,请参考同作者的另外一篇文章_"_Go: How Does the Garbage Collector Mark the Memory?

STW的步骤

第一步,抢占所有正在运行的goroutines

第二步,一旦 goroutines被抢占,正在运行的goroutines将在安全的地方暂停,然后所有的p[1]都将被标记为暂停,停止运行任何代码。

第三步,然后,go调度器将M[2]与P分离,并且将M放到空闲列表里面。

对于在每个M上运行的Goroutines,它们将在全局队列[3]>中等待:

那么,一旦所有的goroutines都停止了,那么唯一活跃的goroutines (垃圾回收goroutines)将会安全的运行,并且在垃圾回收完成后,重新拉起所有的goroutines。具体情况,可以通过 go trace查看。

System calls

STW时期可能会影响系统调用,因为系统调用可能会在stw时期返回,通过密集执行系统调用的程序来看看怎样处理这种情况,

 func main() { 
 var wg sync.WaitGroup 
 wg.Add(10)  for i :\= 0; i < 10; i++ { 
 go func() { 
 http.Get(\`https://httpstat.us/200\`) 
 wg.Done() 
 }() 
 }  wg.Wait() 
 }

他的trace情况。

系统调用在STW时期返回,但是现在已经没有P在运行了。所以他会放到全局队列里面,等待STW结束后再运行。

Latencies

STW的第三步将所有的M与P分离。然而,go将等待调度程序运行、系统调用等自动停止。等待goroutine被抢占应该很快,但是在某些情况下会产生一些延迟,下面是一个极端的例子:

 func main() { 
 var t int 
 for i :\= 0;i < 20 ;i++ { 
 go func() { 
 for i :\= 0;i < 1000000000 ;i++ { 
 t++ 
 } 
 }() 
 } 
 ​ 
 runtime.GC() 
 }

STW时长达到了2.6S

没有函数调用的goroutine将不会被抢占,并且它的P在任务结束之前不会被释放。这将迫使STW等待他, 有几种解决方案可改善循环中的抢占,有关其的更多信息,可以查看作者另外一篇文章 [Go: Goroutine and Preemption).


有疑问加站长微信联系(非本文作者)

本文来自:Segmentfault

感谢作者:yixiao

查看原文:go怎样做stw

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
3518 次点击
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏