一.业内常见的垃圾回收算法
1.引用计数:对每个对象维护一个引用计数,当引用计数为0的时候,回收该对象。
- 优点:对象可以很快的回收,而不会出现内存耗尽或者达到某个阈值时才回收。
- 缺点:不能很好处理循环引用,维护引用计数也有一定的代价。
2 标记-清除:从根来遍历所有引用的对象,没有可以访问到的对象就会被回收。
- 优点:解决引用计数的缺点
- 缺点:需要STW,会暂时停止程序运行进行回收内存的处理。
3 分代收集:按照对象生命周期的长短分为不同的代空间,生命周期长的放入老年代,而短的放入新生代,不同代有不同的回收算法和回收频率
- 优点:回收性能好
- 缺点:算法复杂
二.Go垃圾回收
- 标记出哪些内存还在使用,哪些内存不再使用,把未被引用的内存回收,以供后续内存分配时使用。
- Go三色标记法,其中三色标记法对应了GC中的对象中的状态
- 白色:对象未被标记,白色对象会被GC中请求。
- 黑色:对象已被标记,黑色对象不会被GC中请求
- 灰色:对象等待被标记分析
- 只要是新创建的对象,默认我们标记为
白色
- 每次GC回收的时候,我们从根节点开始遍历所有对象,把遍历到的对象从白色集合放入到"灰色"集合。
- 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将灰色对象放入到黑色集合
- 重复上述,直到灰色集合中没有对象
- 回收所有白色标记的对象,也就是回收垃圾
三.垃圾回收的触发时机
- 内存分配量达到阈值触发
阈值 = 上次GC内存分配量 * 内存增长率
- 定时触发GC
var forcegcperiod int64 = 2 * 60 * 1e9
默认情况下,最长2分钟触发一次