golang 垃圾回收

gc不回收什么

  • GC 不负责回收栈中的内存
  • 栈是一块专用内存,专门为了函数执行而准备的,存储着函数中的局部变量以及调用栈
  • 栈中的数据可以通过简单的编译器指令自动清理,也就不需要通过 GC 来回收了

垃圾回收算法

  • 主流的两类垃圾回收算法有两种,分别是追踪式垃圾回收算法[1]和引用计数法( Reference counting )。而三色标记法是属于追踪式垃圾回收算法的一种
  • 追踪式算法的核心思想是判断一个对象是否可达,因为一旦这个对象不可达就可以立刻被 GC 回收了
  • 第一步找出所有的全局变量和当前函数栈里的变量,标记为可达。第二步,从已经标记的数据开始,进一步标记它们可访问的变量,以此类推,专业术语叫传递闭包。

三色标记法

  • 对象用三种颜色表示,黑白灰。
  • 初始化都是白色的,然后把全局变量和栈上的变量变成灰的
  • 第二步把灰色的对象变成黑色,把原先灰色对象指向的变量变成灰色,以此类推,当发现没有对象可以被制成灰色时,白色的对象就可以清理了

垃圾回收流程

  • 阶段一,marking setup 标记准备,在三色标记前,需要开启 write barrier 写屏障。运行过程中程序的函数栈中会有新分配的对象,就需要写屏障。写屏障主要是修改原先的写逻辑,在对象生成的时候给他着为灰色,因此打开写屏障会保证三色标记法在并发下安全运行
  • 打开写屏障需要停止所有的goroutine,也就是stop the world (STW)
  • 阶段二,marking标记。打开write barrier以后,开始用三色标记法标记。
  • 在标记开始的时候,收集器会默认抢占 25% 的 CPU 性能,剩下的75%会分配给程序执行。但是一旦收集器认为来不及进行标记任务了,就会改变这个 25% 的性能分配。这个时候收集器会抢占程序额外的 CPU,这部分被抢占 goroutine 有个名字叫 Mark Assist 标记辅助。而且因为抢占 CPU的目的主要是 GC 来不及标记新增的内存,那么抢占正在分配内存的 goroutine 效果会更加好,所以分配内存速度越快的 goroutine 就会被抢占越多的资源。
  • 阶段三,Mark termination 标记结束
  • marking标记阶段结束后进入标记结束阶段,会关掉写屏障,开始stw,还需要计算下次清理的目标和计划,比如使用了mark assist 标记辅助,会促使下次gc提前
  • 第四个阶段 sweeping concurrent 清理阶段,并发执行,无感知也没有延迟
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值