GO语言-GC

引言

        垃圾回收机制是高级语言常见的一类内存资源管理方式,C/C++这类语言内存分配及回收很大的主动权在调用者,gc机制较弱;像JAVA、PYTHON及后来的GOLANG都添加了GC机制来减少编程人员的内存管理压力。但于此同时也带来了gc效率问题,接下来我们看下常见的GC方式。

GC算法

        常见GC方式有引用计数(reference counting)、标记-清除(mark & sweep)、节点复制(Copying Garbage Collection),分代收集(Generational Garbage Collection)。

    引用计数

        引用计数算是在gc算法中最简单,也是最直接的gc算法。引用计数是在对象赋值操作时进行额外的清除操作,赋值时减少右值对象所有域的引用计数,计数为0立即进行垃圾处理,不需要STW。但对于环形数据问题(循环引用)无法回收,导致内存泄露。

    标记-清除

        标记-清除根据字面意思已经很明显了,分两步走:

            第一,标记对象

            第二,清除对象(残忍)

        标记还在使用的对象,清除不用的对象,回收资源。那程序在运行时可能改变对象,所以STW(STOP THE WORLD)上场。意思就是有那么一瞬间,程序是暂停运行的。待清除完不用的对象然后继续运行原来的程序。这样的运行原理导致程序可能出现走走停停(可能对你无感知),这个标记清除的时机怎么确定呢???!!!

    节点复制

          copy gc算法是分配A和B空间(学名Allocation Space和Survivor Space),程序在空间A生成对象时,如果没有空间可用则触发一次GC,遍历A空间全部变量是否存活(使用),如果存活状态则复制到B空间,然后清除A空间(此时全是垃圾变量),然后再讲B空间变量移动到A空间。

    分代收集

        分代收集算法主要考虑对象的生命周期,大部分对象的生命周期较短,小部分对象的生命周期较长(2-8定律?)。尽可能的减少gc扫描生命周期较长的对象来提高gc效率。将新创建的对象归入新生代,随着扫描的进行将新生代剩余对象归入老生代,扫描主要在新生代进行,这类扫描叫小扫描。但老生代对象也可能耗尽生命,所以每隔段时间还需要一次对老生代的扫描,称之为大扫描。在新生代扫描时,新生代对象可能只被老生代对象引用,不能将其标记为“可回收”,需要引入记录集记录该情况,即写屏障机制(write barrier)。

GO语言GC机制及演进

    STW-标记-清除(V1.3以前)

        go开始GC版本很暴力,暂停整个程序然后执行标记清除,然后再恢复运行。这对高并发低延迟要求的程序来说应该是灾难了(反正我没经历这一版);当时的解决方案是什么呢,猜,也是像C/C++一样自行控制内存,减少gc次数来减少这种情况的发生吧。

    标记-清除(V1.3)

        如果在了解stw-标记-清除原理的情况下优化该gc方式,你会想到什么呢?

        1.3版本聪明的程序员们又开始“想办法”了,标记阶段必须暂停程序,但清除阶段没必要暂停程序逻辑,两者可以并行进行。so该版本优化了标记-清除的gc方式,减少程序暂停时间来减少“卡顿”提升GC效率。但该方法只是优化(提升还是很多的,go team自己的说法是减少了50%-70%的暂停时间),没有从根本上解决问题,要想继续提升还得继续“想”!

    三色标记(V1.5)

        三色标记是对标记清除的进一步改进,v1.3版本改进了清除逻辑与业务逻辑的并发。标记过程能不能也不停止程序运行呢?!答案是肯定的,只是引入了更多机制(写屏障(write barrier) )。开始都为白色,标记可达对象为灰色,然后被灰色对象引用的对象为灰色,此时标记原来的灰色对象为黑色,最终白色对象被清除。如果此时有新对象生成就标记为灰色,如果引用了白色对象则触发写屏障机制来处理该白色对象。这样就能与用户的业务逻辑并发了。

    混合写屏障(V1.8)

        Golang 1.7 之前的 write barrier 使用的经典的 Dijkstra-style insertion write barrier [Dijkstra ‘78], STW 的主要耗时就在 stack re-scan 的过程。自 1.8 之后采用一种混合的 write barrier 方式 (Yuasa-style deletion write barrier [Yuasa ‘90] 和 Dijkstra-style insertion write barrier [Dijkstra ‘78])来避免 re-scan。

总结

        GOLANG的垃圾回收优化是不断进行的,从最初的集中式gc(stw)到后来分散处理gc(与业务代码并行),用户感知上削弱了但不代表总的gc时间减少。所以还需尽可能控制GC触发提高效率。至于何时触发GC及怎么减少代码GC次数,且听下章分解吧-.-

引用

    Golang 垃圾回收剖析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259