系统相关
首页 > 系统相关> > golang 垃圾回收和内存逃逸分析

golang 垃圾回收和内存逃逸分析

作者:互联网

1. golang垃圾回收

golang的垃圾回收算法是三色标记法,其中三个颜色分别为:灰色、黑色、白色,其对应了垃圾回收过程中变量的三种状态:

 

1.1 垃圾回收流程

假设现在有这么几个对象:

 

有A-F六个对象,根对象a b为栈区分配的局部变量,根对象a b分别引用了对象 A B,而对象B有引用了对象D

下面简单看一下这几个对象的回收流程:

(1) 初始化:初始化时所有的对象都是白色

(2) 扫描:开始扫描根对象a b,由于a b引用了A B,所以A B设置为灰色

 

(3) 分析:分析对象A,A没有引用其他对象,将A设置为黑色,B引用了D对象,则将B设置为黑色的同时,将D设置为灰色

 

(4)结束:重复步骤3,直到灰色队列为空,这时黑色队列中的对象会被保留,白色队列会被回收

 

 

1.2 GC原理

GC的原理简单来讲就是标记内存中哪些还在使用,哪些不被使用,而不被使用的部分就是GC的对象。

root区域主要是指程序运行到当前时刻的栈和全局数据区域,是正在使用到的内存,当然应该优先标记,而考虑到内存块中可能存放的事指针,所以开需要扫描灰色队列进行递归标记,待灰色队列为空,就可以将白色标记回收

 

1.3 GC优化

golang的垃圾回收算法属于标记-清除,是需要STW的,在golang中就是要停掉所有goroutine,进行垃圾回收,待垃圾回收结束后再恢复goroutine。

所以,STW时间的长短直接影响了应用的执行,为了缩短STW时长,golang优化的GC算法,其中写屏障和辅助GC就是两种优化垃圾回收的方法

写屏障:

  STW的目的是为了防止GC在扫描时出现内存变化而产生混乱,写屏障就是让goutine和GC同时运行,虽然不能完全消除STW,但可以大幅端减少STW时长。

  写屏障在GC的特定时间开启,开启后指针传递时会把指针标记,即本轮不回收,下次GC时再确定。

辅助GC:

  为了防止内存分配过快,在GC执行过程中,GC过程中mutator线程会并发运行,而mutator assisit机制会协助GC做一部分的工作。

 

1.4 GC触发机制

 

1.5 GC调优

 

2. 内存逃逸分析

golang中堆栈对于程序员是透明的,栈空间回收更快,堆空间需要触发GC。

逃逸分析,可以尽量把那些不需要分配到堆上的变量直接分配到栈上。

 

2.1 逃逸分析

逃逸分析一个最基本的原则就是:如果一个函数返回对一个变量的引用,那么它就会发生逃逸

逃逸的常见情况:

 

2.2 如何避免内存逃逸

 

标签:对象,回收,golang,逃逸,GC,内存,指针
来源: https://www.cnblogs.com/aganippe/p/16022689.html