来源:自学PHP网 时间:2019-08-07 16:43 作者:小飞侠 阅读:次
[导读] 图解Golang的GC垃圾回收算法...
虽然Golang的GC自打一开始,就被人所诟病,但是经过这么多年的发展,Golang的GC已经改善了非常多,变得非常优秀了。 以下是Golang GC算法的里程碑:
经典的GC算法有三种: Golang的GC算法主要是基于 标记-清扫(Mark And Sweep)算法 此算法主要有两个主要的步骤:
第一步,找出不可达的对象,然后做上标记。 第二步,回收标记好的对象。 操作非常简单,但是有一点需要额外注意: 也就是说,这段时间程序会卡在哪儿。故中文翻译成 我们来看一下图解: 开始标记,程序暂停。程序和对象的此时关系是这样的: 然后开始标记,process找出它所有可达的对象,并做上标记。如下图所示: 标记完了之后,然后开始清除未标记的对象: 然后 最后,停止暂停,让程序继续跑。然后循环重复这个过程,直到 标记-清扫(Mark And Sweep)算法存在什么问题?
这里面最重要的问题就是:mark-and-sweep 算法会暂停整个整个程序。 Go是如何面对并这个问题的呢? 三色并发标记法 我们先来看看Golang的三色标记法的大体流程。 首先:程序创建的对象都标记为白色。 gc开始:扫描所有可到达的对象,标记为灰色 从灰色对象中找到其引用对象标记为灰色,把灰色对象本身标记为黑色 监视对象中的内存修改,并持续上一步的操作,直到灰色标记的对象不存在 此时,gc回收白色对象。 最后,将所有黑色对象变为白色,并重复以上所有过程。 好了,大体的流程就是这样的,让我们回到刚才的问题:Go是如何解决 gc和用户逻辑如何并行操作? 标记-清除(mark and sweep)算法的STW(stop the world)操作,就是runtime把所有的线程全部冻结掉,所有的线程全部冻结意味着用户逻辑是暂停的。这样所有的对象都不会被修改了,这时候去扫描是绝对安全的。 Go如何减短这个过程呢?标记-清除(mark and sweep)算法包含两部分逻辑:标记和清除。 我们知道Golang三色标记法中最后只剩下的黑白两种对象,黑色对象是程序恢复后接着使用的对象,如果不碰触黑色对象,只清除白色的对象,肯定不会影响程序逻辑。所以: 标记操作和用户逻辑也是并发的,用户逻辑会时常生成对象或者改变对象的引用,那么标记和用户逻辑如何并发呢? process新生成对象的时候,GC该如何操作呢?不会乱吗? 我们看如下图,在此状态下:process程序又新生成了一个对象,我们设想会变成这样: 但是这样显然是不对的,因为按照三色标记法的步骤,这样新生成的对象A最后会被清除掉,这样会影响程序逻辑。 Golang为了解决这个问题,引入了 写屏障:该屏障之前的写操作和之后的写操作相比,先被系统其它组件感知。 通俗的讲:就是在gc跑的过程中,可以监控对象的内存修改,并对对象进行重新标记。(实际上也是超短暂的stw,然后对对象进行标记) 在上述情况中, 那么,灰色或者黑色对象的引用改为白色对象的时候,Golang是该如何操作的? 看如下图,一个黑色对象引用了曾经标记的白色对象。 这时候,写屏障机制被触发,向GC发送信号,GC重新扫描对象并标位灰色。 因此,gc一旦开始,无论是创建对象还是对象的引用改变,都会先变为灰色。 参考文献: Golang's Real-time GC in Theory and Practice 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学php网。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com