Golang垃圾回收原理GC

什么是垃圾回收:

Golang的垃圾回收(GC)就是将不再需要的内存块释放掉,否则不能回收的垃圾就是泄露的内存

垃圾回收算法

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

  • 引用计数:对每个对象维护一个引用计数,当引用该对象的对象被销毁时,引用计数减1,当引用计数器为0时回收该对象。
    • 优点:对象可以很快地被回收,不会出现内存耗尽或达到某个阀值时才回收。
    • 缺点:不能很好地处理循环引用,而且实时维护引用计数,也有一定的代价。
    • 代表语言:Python、PHP、Swift
  • 标记-清除:从根变量开始遍历所有引用的对象,引用的对象标记为”被引用”,没有被标记的进行回收。
    • 优点:解决了引用计数的缺点。
    • 缺点:需要STW,即要暂时停掉程序运行。
    • 代表语言:Golang(其采用三色标记法)
  • 分代收集:按照对象生命周期长短划分不同的代空间,生命周期长的放入老年代,而短的放入新生代,不同代有不同的回收算法和回收频率。
    • 优点:回收性能好
    • 缺点:算法复杂
    • 代表语言: JAVA

Golang垃圾回收机制

简单流程:

垃圾回收开始时从root对象开始扫描,把root对象引用的内存标记为”被引用”,考虑到内存块中存放的可能是指针,所以还需要递归的进行标记,全部标记完成后,只保留被标记的内存,未被标记的全部标识为未分配即完成了回收。

 内存标记底部结构:

之前讲内存分配的时候,介绍过span数据结构,span中维护了一个个内存块,并由一个位图allocBits表示每个内存块的分配情况(带指针的部分)。在span数据结构中还有另一个位图gcmarkBits用于标记内存块被引用情况。

 

三色标记法

实际上我们将标记的,未标记的,待标记的区分开来,分别进行操作。那么我们实际操作时的逻辑,抽象一下,就是“三色标记法”。

这里的三色,对应了垃圾回收过程中对象的三种状态:

  • 灰色:对象还在标记队列中等待
  • 黑色:对象已被标记,gcmarkBits对应的位为1(该对象不会在本次GC中被清理)
  • 白色:对象未被标记,gcmarkBits对应的位为0(该对象将会在本次GC中被清理)

 最一开始,所有对象(A~F)都是白色对象

之后扫码Root对象,发现引用了AB,便将AB放入灰色对象进行分析、

发现A无引用其他对象,B还引用了D。便将AB放入黑色对象同时D放入灰色对象再分析,最后D也放入黑色对象

最后将所有白色对象回收

垃圾回收触发时机

  • 内存分配量达到阀值触发GC(阀值 = 上次GC内存分配量 * 内存增长率)
  • 定期触发GC(默认情况下,最长2分钟触发一次GC)
  • 手动触发(runtime.GC())

 GC优化

GC性能与对象数量负相关,对象越多GC性能越差,对程序影响越大。

所以GC性能优化的思路之一就是减少对象分配个数,比如对象复用或使用大对象组合多个小对象等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值