Golang GC原理
Golang 从诞生之处到现在对GC做了诸多改进,目前用的GC算法为三色标记算法。
基础知识
在说三色标记算法之前,必须要了解一些基本的概念,否则无法真正理解Golang的GC算法
通常,一个垃圾回收器的执行过程被分为两个部分。
赋值器:程序中的代码,对于垃圾回收器而言,关注的对象之间的引用,这些相互之间的引用,就构成了一张有向图,操作对象,也就是操作对象之间的引用关系。
回收器:负责垃圾回收,找到上述中的不被引用的对象,清除并回收内存。
另外一个需要了解的概念就是根对象(在垃圾回收机制中叫做根集合),他包括:
全局变量:这些程序在编译期间就能够确定
执行栈: Goroutine上包含的变量以及指向堆内存的指针等
还有其他指向堆内存区块的指针等等。
STW
因为回收而暂停,在1.14之后已经不会出现。
常见的GC算法
主要分为两类:
追踪式GC: 从根集合出发,逐层遍历对象的引用信息,找出保留的对象,回收所有可以回收的对象,GO、JAVA等都是用这种方式。
引用式GC: 每个对象的引用都包含一个被引用的计数,当为0时,回收
三色标记法
如下图所示,三色标记法,规定了三种不同类型的对象:
- 白色对象:未被回收器访问到的对象,在回收的初始阶段,所有的对象,均为白色,当回收结束后,白色对象均不可达,意味着将被回收。
- 灰色对象:回收器访问到的对象,但回收器,需要对其中的一个或多个指针进行扫描,查看是否还能到达白色对象。
- 黑色对象:回收器访问的对象,且不会到达白色对象,意味着是活跃的对象,不需要被清除。
查看回收现象
1 |
|
1 |
|
屏障机制
标记受到并发的影响,可能会导致对象错误回收,所以在此之前需要做一定的处理,屏障机制,类似一个钩子函数。
具体操作
1、GC开始将栈上的对象全部扫描并标记为黑色(之后不再进行第二次重复扫描,无需STW),
2、GC期间,任何在栈上创建的新对象,均为黑色。
3、被删除的对象标记为灰色。
4、被添加的对象标记为灰色。
Golang GC原理
https://www.xinyublog.com/golang/gc/