go 垃圾回收

本文深入探讨了Go语言的垃圾回收机制,包括并发GC、写屏障、堆区回收及四个阶段:sweeptermination、mark、marktermination和sweep。GC速率由GOGC参数控制,写屏障确保并发标记的正确性。同时,介绍了GC如何避免碎片内存,以及在不同阶段对mutator线程的影响。
摘要由CSDN通过智能技术生成

参考链接一(外网)
参考二:源码的注释

  • golang的gc可以与mutator线程并发执行,而且允许多个gc线程并行。
  • 支持并发的mark和sweep,也会使用写屏障。
  • 按P来分配隔离的空间来减少碎片内存。
  • mcache是没有GC的区域,所以有下面说的把mcache放到central cache中来进行垃圾回收。
  • 堆区的回收是通过Arena的bitmap来快速定位。
  • Mark阶段会占用25%的CPU,其实大概就是会占用25%的P

gc的四个阶段

  1. sweep termination
    a. 此过程会引发STW,所有的P都会到安全点safe-point;
    b. 回收未被回收的spans(内存管理单元),只有gc被强制开始才会有未被回收的spans;
  2. mark
    a. 将gc状态从_GCoff改成_GCmark,让所有的P打开write barrier和GC辅助(就是正在工作的G协助完成gc),把扫描标记的任务放入队列,打开写屏障这段时间是STW的,write barrier没打开完成,扫描工作就不会进行;
    b. start the world。用写屏障覆盖,并将所有新分配的对象标成黑色;
    c. 标记根节点。扫描所有goroutines栈区指向堆区的指针和全局对象,扫描栈区指针时会将对应的goroutine暂停,等扫描完成再让它继续运行,将找到的对象放到灰色对象队列中;
    d. 扫描所有队列中的灰色对象,将他们标成黑色,并将这些对象包含的对象放到灰色队列中;
  3. mark termination
    a. STW,将gc状态改成_GCmarktermination,关闭GC辅助和工作线程,计算下一次GC计划;
    b. 将mcaches放到central cache;
  4. sweep
    a. 将gc状态改成_GCoff
    b. Start the world。从这一刻开始,新分配的对象将是白色的,
    c. gc并发地后台清理对象,在这个阶段,gc会用一个后台goroutine挨个清除span,这个阶段当有一个goroutine需要分配一个小对象但是空间不够时,并不会向操作系统申请空间,而是清除小对象,直到够那个goroutine分配。当需要在heap分配大对象时,也是一样的操作。
    总之,不能在未被清扫过的span中搞活动,而且GC过程中mcache会被放到central cache中,如果在此期间有goroutinemcache中分配对象,这个goroutine清扫掉这个对象。
    当所有的spans被清除过,GC就会结束
  • GC的速率
    当新分配的空间与正在使用的空间形成一定比例,就会触发下一次GC,这个比例有参数GOGC控制,比如GOGC=100,此时空间利用为4M,当空间用到8M时,就会触发GC。
  • 写屏障
    并发Mark的阶段,黑色节点不会被扫描,但如果这段时间黑色节点又引用其他对象就会导致该对象还是白色,不会加入灰色对象链表。用写屏障来解决这个问题:其实就是在内存每次写入时都加上一段代码,把被引用的对象标成灰色。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值