golang 垃圾回收机制

golang 垃圾回收机制

术语

  • allocator
  • collector

自动内存管理机制一般包含allocator(分配器)和collector(回收器)。allocator负责为应用代码分配对象,而collector则负责寻找存活的对象,并释放不再存活的对象

  • mutator

mutate的是变化的意思,mutator就是改变者,在GC里,指的是改变对象之间引用关系的实体,可以简单的理解为我们写的的应用程序(运行我们写的代码的线程, 协程)。

golang垃圾回收算法-三色标记法

三色标记是以标记清除为基础的,解决了引用计数的缺点,但是会STW

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3kiHnBkB-1625979103192)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4f5a0898-501b-4672-80d4-11c3ae89b576/Untitled.png)]

灰:还在标记队列中等待

黑:已被标记,gcmarkBits对应位为1,该对象不会被gc

白:未被标记,gcmarkBits对应位为0,该对象会在本次gc中被清理

注:由于有些存放的是指针,所以要进行递归标记,等待全部标记完成后,我们再进行内存回收

内存标记

golang 中采用 span 数据结构管理内存,span 中维护了一个个内存块,并由一个位图 allocBits 表示内存块的分配情况,而上文中提到的 gcmarkBits 是记录每块内存块被引用情况的。

https://img-blog.csdnimg.cn/20201220101827285.png

allocBits 记录了每块内存的分配情况,而 gcmarkBits 记录了每块内存的标记情况。在标记阶段会对每块内存进行标记,有对象引用的内存标记为 1,没有对象引用的为 0。而 allocBits 和 gcmarkBits 的数据结构是完全一样的,在结束标记后,将 allocBits 指向 gcmarkBits,则有标记的才是存活的,这样就完成了内存回收。而 gcmarkBits 则会在下次标记时重新分配内存。

垃圾回收

标记内存中那些保留数据,而内存中不再使用的数据,就是要回收的垃圾,需要将其回收,以供后续内存分配使用。上图中的 A、B、D 就是被引用正在使用的内存,而C、F、E 曾经被使用过,但现在没有任何对象引用,就需要被回收掉。

Root 区域主要是程序运行到当前时刻的栈和全局数据区域,是实时正在使用到的内存,当然应该优先标记。而考虑到内存块中存放的可能是指针,所以还需要递归的进行标记,待全部标记完后,就会对未被标记的内存进行回收。

垃圾回收触发机制

  • 内存分配量达到阈值:每次内存分配都会检查当前内存分配量是否达到阈值,如果达到阈值则触发 GC。阈值 = 上次 GC 内存分配量 * 内存增长率,内存增长率由环境变量 GOGC 控制,默认为 100,即每当内存扩大一倍时启动 GC。
  • 定时触发 GC:默认情况下,2分钟触发一次 GC,该间隔由 src/runtime/proc.go 中的 forcegcperiod 声明。
  • 手动触发 GC:在代码中,可通过使用 runtime.GC() 手动触发 GC。

垃圾回收优化

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

  • 写屏障(Write Barrier):上面说到的 STW 的目的是防止 GC 扫描时内存变化引起的混乱,而写屏障就是让 goroutine 与 GC 同时运行的手段,虽然不能完全消除 STW,但是可以大大减少 STW 的时间。写屏障在 GC 的特定时间开启,开启后指针传递时会把指针标记,即本轮不回收,下次 GC 时再确定。
  • 辅助 GC(Mutator Assist):为了防止内存分配过快,在 GC 执行过程中,GC 过程中 mutator 线程会并发运行,而 mutator assist 机制会协助 GC 做一部分的工作。

参考:

Golang垃圾回收机制_!一直往南方开.的博客-CSDN博客_golang垃圾回收机制

go java gc_Golang GC(垃圾回收机制)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值