day4 go语言GC垃圾回收 | 青训营笔记

87 阅读3分钟

这是我参加第五届青训营伴学笔记创作活动的第三天

垃圾回收算法

业界常见的垃圾回收算法有以下几种 业界常见的垃圾回收算法有以下几种:

  • 引用计数:对每个对象维护一个引用计数,当引用该对象的对象被销毁时,引用计数减1,当引用计数器为0是回收该对象。

    • 优点:对象可以很快的被回收,不会出现内存耗尽或达到某个阀值时才回收。
    • 缺点:不能很好的处理循环引用,而且实时维护引用计数,有也一定的代价。
    • 代表语言:Python、PHP、Swift
  • 标记-清除:从根变量开始遍历所有引用的对象,引用的对象标记为”被引用”,没有被标记的进行回收。

    • 优点:解决了引用计数的缺点。
    • 缺点:需要STW,即要暂时停掉程序运行。
    • 代表语言:Golang(其采用三色标记法)
  • 分代收集:按照对象生命周期长短划分不同的代空间,生命周期长的放入老年代,而短的放入新生代,不同代有不同的回收算法和回收频率。

    • 优点:回收性能好
    • 缺点:算法复杂
    • 代表语言: JAVA

GO垃圾回收

原理

简单的说,垃圾回收的核心就是标记出哪些内存还在使用中(即被引用到),哪些内存不再使用了(即未被引用),把未被引用的内存回收掉,以供后续内存分配时使用。

image.png

GO的回收算法

Go V1.3之前的标记-清除(mark and sweep)算法

image.png 1.暂停业务逻辑,暂停程序业务逻辑, 分类出可达和不可达的对象,然后做上标记。 2.开始标记,程序找出它所有可达的对象,并做上标记。 3.标记完了之后,然后开始清除未标记的对象。 4.停止暂停,让程序继续跑。然后循环重复这个过程,直到process程序生命周期结束。

优点:简单明了

缺点:STW会暂停整个程序,出现程序卡顿

Go V1.5的三色并发标记法

和上述类似,只是节点依次从白——灰——黑,同样需要STW的时间。

混合写屏障

有两种情况,在三色标记法中,是不希望被发生的。不存在黑色对象引用到白色对象的指针

  • 条件1: 一个白色对象被黑色对象引用 (白色被挂在黑色下)
  • 条件2: 灰色对象与它之间的可达关系的白色对象遭到破坏 (灰色同时丢了该白色)
    如果当以上两个条件同时满足时,就会出现对象丢失现象!

屏障机制

我们让GC回收器,满足下面两种情况之一时,即可保对象不丢失。  这两种方式就是“强三色不变式”和“弱三色不变式”

  • 强三色不变式

不存在黑色对象引用到白色对象的指针

image.png

  • 弱三色不变式

所有被黑色对象引用的白色对象都处于灰色保护状态。

image.png

GoV1.3- 普通标记清除法,整体过程需要启动STW,效率极低。

GoV1.5- 三色标记法, 堆空间启动写屏障,栈空间不启动,全部扫描之后,需要重新扫描一次栈(需要STW),效率普通

GoV1.8-三色标记法,混合写屏障机制, 栈空间不启动,堆空间启动。整个过程几乎不需要STW,效率较高。