教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Golang的垃圾回收(GC)机制

Golang的垃圾回收(GC)机制

发布时间:2022-01-28   编辑:jiaochengji.com
教程集为您提供Golang的垃圾回收(GC)机制等资源,欢迎您收藏本站,我们将为您提供最新的Golang的垃圾回收(GC)机制资源

<article>

<span style="color:#333333;">转载自https://blog.csdn.net/liangzhiyang/article/details/52670021</span>

<span style="box-sizing: border-box; outline: 0px; word-break: break-all; color: rgb(51, 51, 51);">请先阅读</span><span style="box-sizing: border-box; outline: 0px; color: rgb(51, 51, 51); text-decoration-line: none; cursor: pointer; word-break: break-all;"> </span><span style="box-sizing: border-box; outline: 0px; color: rgb(50, 108, 166); text-decoration-line: none; cursor: pointer; word-break: break-all;">golang</span><span style="box-sizing: border-box; outline: 0px; color: rgb(50, 108, 166); text-decoration-line: none; cursor: pointer; word-break: break-all;">的</span><span style="box-sizing: border-box; outline: 0px; color: rgb(50, 108, 166); text-decoration-line: none; cursor: pointer; word-break: break-all;">goroutine</span><span style="box-sizing: border-box; outline: 0px; color: rgb(50, 108, 166); text-decoration-line: none; cursor: pointer; word-break: break-all;">调度机制</span><span style="color: rgb(51, 51, 51);">然后再到这里</span>

<span style="color:#333333;">
</span>

<span style="color:#333333;">golang</span><span style="color:#333333;">的垃圾回收</span><span style="color:#333333;">采用的是</span><span style="color:#333333;"> </span><span style="color:#333333;">标记</span><span style="color:#333333;">-</span><span style="color:#333333;">清理(</span><span style="color:#333333;">Mark-and-Sweep</span><span style="color:#333333;">)</span><span style="color:#333333;"> </span><span style="color:#333333;">算法</span>

<span style="color:#333333;">就是先标记出需要回收的内存对象快,然后在清理掉;</span>

<span style="color:#333333;">在这里不介绍</span><span style="color:#333333;">标记和清理的具体策略(可以参考https://lengzzz.com/note/gc-in-golang),只介绍</span><span style="color:#333333;"> GC</span><span style="color:#333333;">过程是怎么调度的以及</span><span style="color:#333333;">stw</span><span style="color:#333333;">相关</span>

<span style="color:#333333;">这个算法,会导致</span><span style="color:#333333;"> stw (stop the world)</span><span style="color:#333333;">的问题,中断用户逻辑</span>

<span style="color:#333333;">触发</span><span style="color:#333333;">GC</span><span style="color:#333333;">机制</span>

<span style="color:#333333;">1.    </span><span style="color:#333333;">在申</span><span style="color:#333333;">请</span><span style="color:#333333;">内存的</span><span style="color:#333333;">时</span><span style="color:#333333;">候,</span><span style="color:#333333;">检查</span><span style="color:#333333;">当前当前已分配的内存是否大于上次</span><span style="color:#333333;">GC</span><span style="color:#333333;">后的内存的</span><span style="color:#333333;">2</span><span style="color:#333333;">倍,若是</span><span style="color:#333333;">则</span><span style="color:#333333;">触</span><span style="color:#333333;">发</span><span style="color:#333333;">(主</span><span style="color:#333333;">GC</span><span style="color:#333333;">线程为当前</span><span style="color:#333333;">M</span><span style="color:#333333;">)</span>

<span style="color:#333333;">2.    </span><span style="color:#333333;">监控线程发现上次</span><span style="color:#333333;">GC</span><span style="color:#333333;">的</span><span style="color:#333333;">时间</span><span style="color:#333333;">已</span><span style="color:#333333;">经</span><span style="color:#333333;">超</span><span style="color:#333333;">过</span><span style="color:#333333;">两分</span><span style="color:#333333;">钟</span><span style="color:#333333;">了,触</span><span style="color:#333333;">发</span><span style="color:#333333;">;将一个</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">放到全局</span><span style="color:#333333;">G</span><span style="color:#333333;">队列中去。(主</span><span style="color:#333333;">GC</span><span style="color:#333333;">线程为执行这个</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">的</span><span style="color:#333333;">M</span><span style="color:#333333;">)</span>

<span style="color:#333333;"> </span>

<span style="color:#333333;">每当触发的时候,在主</span><span style="color:#333333;">GC</span><span style="color:#333333;">线程中就会走如下的</span><span style="color:#333333;">GC</span><span style="color:#333333;">流程:</span>

<span style="color:#333333;">1.    </span><span style="color:#333333;">stop the world</span><span style="color:#333333;">,等待所有的</span><span style="color:#333333;">M</span><span style="color:#333333;">休眠;此</span><span style="color:#333333;">时</span><span style="color:#333333;">所有的</span><span style="color:#333333;">业务逻辑</span><span style="color:#333333;">代</span><span style="color:#333333;">码</span><span style="color:#333333;">都停止</span>

<span style="color:#333333;">2.    </span><span style="color:#333333;">标记:分配</span><span style="color:#333333;">gc</span><span style="color:#333333;">标记任务,唤醒</span><span style="color:#333333;"> gcproc</span><span style="color:#333333;">个</span><span style="color:#333333;"> M</span><span style="color:#333333;">(就是第一步休眠的那些),分</span><span style="color:#333333;">别</span><span style="color:#333333;">做</span><span style="color:#333333;">这</span><span style="color:#333333;">个,直到所有的</span><span style="color:#333333;">M</span><span style="color:#333333;">都做完,才</span><span style="color:#333333;">结</span><span style="color:#333333;">束;并且所有</span><span style="color:#333333;">M</span><span style="color:#333333;">再次</span><span style="color:#333333;">进</span><span style="color:#333333;">入休眠</span>

<span style="color:#333333;">3.    </span><span style="color:#333333;">清理:有一个</span><span style="color:#333333;">单</span><span style="color:#333333;">独的</span><span style="color:#333333;">goroutine</span><span style="color:#333333;">去清理已</span><span style="color:#333333;">经标记</span><span style="color:#333333;">的内存</span><span style="color:#333333;">对</span><span style="color:#333333;">象快</span>

<span style="color:#333333;">4.    </span><span style="color:#333333;">start the world</span><span style="color:#333333;">,</span><span style="color:#333333;">设</span><span style="color:#333333;">置</span><span style="color:#333333;">gcwaiting=0</span><span style="color:#333333;">,</span><span style="color:#333333;">唤</span><span style="color:#333333;">醒所有的</span><span style="color:#333333;">M</span><span style="color:#333333;">(不会超</span><span style="color:#333333;">过</span><span style="color:#333333;">P</span><span style="color:#333333;">个数)</span>

<span style="color:#333333;"> </span>

<span style="color:#333333;">对于上面的三个步骤,分别解释:</span>

<span style="color:#333333;">stop the world</span><span style="color:#333333;">:</span>

<span style="color:#333333;">1.    </span><span style="color:#333333;">设置</span><span style="color:#333333;">gcwaiting=1</span><span style="color:#333333;">,</span><span style="color:#333333;">这</span><span style="color:#333333;">个在每一个</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">之前会</span><span style="color:#333333;">检查</span><span style="color:#333333;">一次</span><span style="color:#333333;">这</span><span style="color:#333333;">个状</span><span style="color:#333333;">态</span><span style="color:#333333;">,如是,</span><span style="color:#333333;">则</span><span style="color:#333333;">会将当前</span><span style="color:#333333;">M</span><span style="color:#333333;">休眠;</span>

<span style="color:#333333;">2.    </span><span style="color:#333333;">如果</span><span style="color:#333333;">这</span><span style="color:#333333;">个</span><span style="color:#333333;">M</span><span style="color:#333333;">里面正在运行一个</span><span style="color:#333333;">长时间</span><span style="color:#333333;">的</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">,咋</span><span style="color:#333333;">办</span><span style="color:#333333;">呢,</span><span style="color:#333333;">难</span><span style="color:#333333;">道会等待</span><span style="color:#333333;">这</span><span style="color:#333333;">个</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">自己切</span><span style="color:#333333;">换吗</span><span style="color:#333333;">?</span><span style="color:#333333;">这样</span><span style="color:#333333;">的</span><span style="color:#333333;">话</span><span style="color:#333333;">可要等</span><span style="color:#333333;">10ms</span><span style="color:#333333;">啊,不能等!</span><span style="color:#333333;">坚</span><span style="color:#333333;">决不能等!</span><span style="color:#333333;">
</span><span style="color:#333333;">所以会主</span><span style="color:#333333;">动发</span><span style="color:#333333;">出</span><span style="color:#333333;">抢</span><span style="color:#333333;">占</span><span style="color:#333333;">标记</span><span style="color:#333333;">(</span><span style="color:#333333;">类</span><span style="color:#333333;">似于上一篇),</span><span style="color:#333333;">让</span><span style="color:#333333;">当前</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">中断,再运行下一个</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">的</span><span style="color:#333333;">时</span><span style="color:#333333;">候,就会走到第</span><span style="color:#333333;">1</span><span style="color:#333333;">步</span>

<span style="color:#333333;">3.    </span><span style="color:#333333;">一直等待所有的</span><span style="color:#333333;">M</span><span style="color:#333333;">进入休眠,此时所有的业务逻辑代码都停</span><span style="color:#333333;">止</span>

<span style="color:#333333;">标记:</span>

<span style="color:#333333;">1.    </span><span style="color:#333333;"> </span><span style="color:#333333;">根据</span><span style="color:#333333;">gcproc</span><span style="color:#333333;">的个数,分配成</span><span style="color:#333333;">gcproc</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">段;</span><span style="color:#333333;">唤</span><span style="color:#333333;">醒</span><span style="color:#333333;">gcproc-1</span><span style="color:#333333;">个</span><span style="color:#333333;">M</span><span style="color:#333333;">来</span><span style="color:#333333;">执</span><span style="color:#333333;">行(当前</span><span style="color:#333333;">M</span><span style="color:#333333;">也算一个</span><span style="color:#333333;">)</span>

<span style="color:#333333;">2.    </span><span style="color:#333333;">对于一个</span><span style="color:#333333;">M</span><span style="color:#333333;">,</span><span style="color:#333333;">唤</span><span style="color:#333333;">醒前</span><span style="color:#333333;">设置它的</span><span style="color:#333333;">helpgc</span><span style="color:#333333;">标记,唤醒之后这个</span><span style="color:#333333;">M</span><span style="color:#333333;">会立</span><span style="color:#333333;">马</span><span style="color:#333333;">判断</span><span style="color:#333333;">这</span><span style="color:#333333;">个</span><span style="color:#333333;">标记</span><span style="color:#333333;">,如是,</span><span style="color:#333333;">则</span><span style="color:#333333;">开始做分配</span><span style="color:#333333;">给</span><span style="color:#333333;">自己的</span><span style="color:#333333;">标记</span><span style="color:#333333;">任</span><span style="color:#333333;">务,如果先做完了,就会从别的</span><span style="color:#333333;">M</span><span style="color:#333333;">里面找一些来做</span>

<span style="color:#333333;">3.    </span><span style="color:#333333;">等每一个</span><span style="color:#333333;">M</span><span style="color:#333333;">都做完,会再次</span><span style="color:#333333;">进</span><span style="color:#333333;">入休眠</span>

<span style="color:#333333;">清理:</span>

<span style="color:#333333;">1.    </span><span style="color:#333333;">通</span><span style="color:#333333;">过设</span><span style="color:#333333;">置参数,可以以一个</span><span style="color:#333333;">单</span><span style="color:#333333;">独</span><span style="color:#333333;">goroutine  </span><span style="color:#333333;">运行,</span><span style="color:#333333;">这</span><span style="color:#333333;">个功能是在</span><span style="color:#333333;">1.3</span><span style="color:#333333;">版本之后增加的,</span><span style="color:#333333;">这样</span><span style="color:#333333;">的</span><span style="color:#333333;">话</span><span style="color:#333333;">就直接到下一步了,清理</span><span style="color:#333333;">过</span><span style="color:#333333;">程不是</span><span style="color:#333333;">stw</span><span style="color:#333333;">的</span>

<span style="color:#333333;">2.    </span><span style="color:#333333;">也可以串行的在主</span><span style="color:#333333;">GC</span><span style="color:#333333;">线程执行;这样的话则</span><span style="color:#333333;">清理</span><span style="color:#333333;">过</span><span style="color:#333333;">程也是</span><span style="color:#333333;">stw</span><span style="color:#333333;">的,</span>

<span style="color:#333333;">start the world</span><span style="color:#333333;">:</span>

<span style="color:#333333;">1.    </span><span style="color:#333333;">设置</span><span style="color:#333333;">gcwaiting=0</span>

<span style="color:#333333;">2.    </span><span style="color:#333333;">唤醒</span><span style="color:#333333;">P</span><span style="color:#333333;">个</span><span style="color:#333333;">M</span><span style="color:#333333;">来</span><span style="color:#333333;">继续</span><span style="color:#333333;">做</span><span style="color:#333333;">G</span><span style="color:#333333;">任</span><span style="color:#333333;">务</span><span style="color:#333333;">(此</span><span style="color:#333333;">时</span><span style="color:#333333;">没有</span><span style="color:#333333;">helpgc</span><span style="color:#333333;">标记),业务逻辑代码开</span><span style="color:#333333;">始</span>

<span style="color:#333333;"> </span>

<span style="color:#333333;"> </span>

<span style="color:#333333;">综上:</span>

<span style="color:#333333;">是基于</span><span style="color:#333333;">1.4</span><span style="color:#333333;">版本的,</span><span style="color:#333333;">GC</span><span style="color:#333333;">过程在</span><span style="color:#333333;">标记过程是(</span><span style="color:#333333;">STW</span><span style="color:#333333;">)的</span>

<span style="color:#333333;">在</span><span style="color:#333333;">1.5</span><span style="color:#333333;">版本里面对</span><span style="color:#333333;">GC</span><span style="color:#333333;">做了很大的优化;采用三色标记,将标记过程细化成三段,只有前后的两段是</span><span style="color:#333333;">stw</span><span style="color:#333333;">的;极大地缩短了</span><span style="color:#333333;">gc</span><span style="color:#333333;">的</span><span style="color:#333333;">stw</span><span style="color:#333333;">时间</span>

<span style="color:#333333;">
</span>

</article>



到此这篇关于“Golang的垃圾回收(GC)机制”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Golang理解-垃圾回收机制
Golang垃圾回收机制
golang垃圾回收
大家一起学Golang——轻描淡写GC垃圾回收
php垃圾回收机制处理办法
go 垃圾回收:三色算法
golang 回收机制
golang runtime 简析
Go GC垃圾回收机制
Golang中的垃圾回收算法

[关闭]
~ ~