golang的垃圾回收机制是典型的mask-sweep,标记整理。一般来说,有两种方法可以用来作为标记的方法:
- 引用计数法 2. 可达性分析法
引用计数法的缺陷是:1)频繁更新引用降低了性能 2)无法解决循环引用问题
可达性分析:从根变量迭代遍历到所有被引用变量,没有被遍历到的就是可回收对象
使用三色标记算法:可以渐进执行而不需要每次都去扫描整个空间,减少了stop the world的时间。相比传统的标记清扫算法,三色标记最大的好处是可以异步执行,从而可以以中断时间极少的代价或者完全没有中断来进行整个 GC。
三色标记算法原理(黑白灰):
- 把所有对象都标记为白色;
- 将全局变量和函数栈里的对象置为灰色,从这里开始扫描;
- 如果一个灰色对象g,它的子节点x,y也被扫描完,那么就把g变为黑色,然后把x和y标记为灰色;再从x,y依次往下扫描;
- 扫描结束后仍然为白色的对象就是可回收对象
三色标记算法的缺陷:
会丢失对象。
比如说一个黑色对象引用了一个白色对象,会把这个白色对象给清理掉,但是实际上它是存在引用的