← 返回目录

简述Go的垃圾回收机制

第 27 / 29 卷日期:

简述Go的垃圾回收机制

go目前使用的垃圾回收机制是三色标记法配合写屏障和辅助GC

三色标记法是对标记回收算法的改进:

  1. 初始阶段所有对象都是白色
  2. 从root根出发扫描根对象,将它们引用到的对象都标记为灰色,其中root区域主要是当前程序运行到的栈和全局

数据区域,是实时使用到的内存

  1. 将灰色对象标记为黑色,分析该灰色对象是否引用了其他对象,如果有引用其他对象,就将引用的对象标记为灰色
  2. 不断分析灰色对象,直到灰色对象队列为空,此时白色对象即为垃圾,进行回收

在内存管理中,allocBits记录了每块内存的分配情况,而gcmarkBits记录了每块内存的回收标记情况,在标记阶段会对每块内存进行标记,有对象引用的标记为1,没有的标记为0,结束标记后,将allocBits指向gcmarkBits,则有标记的才是

存活的内存块,这样就完成了内存回收

进行垃圾回收需要进行STW,如果STW时间过长对于应用执行来说是灾难性的,因此为了缩短STW的时间,golang引入了写屏障和辅助GC

写屏障是让GC和应用程序并发执行的手段,可以有效减少STW的时间

辅助GC是为了防止GC过程中内存分配的速度过快,因此会在GC过程中让mutator线程并发执行,协助GC执行一部分回收工作

GC触发机制有:

  1. 内存分配量达到阈值:每次内存分配前都会检查当前内存分配量是否达到阈值,如果达到则触发GC, 阈值=上次

GC时的内存分配量 * 内存增长率

  1. 定时触发GC:默认情况下两分钟触发一次GC,可由runtime中的参数声明
  2. 手动触发GC:可以在代码中通过使用runtime.GC()来手动触发

select实现机制

1、锁定scase中所有channel

2、按照随机顺序检测scase中的channel是否ready

(1)如果case可读,读取channel中的数据(2)如果case可写,写入channel

(3)如果都没准备好,就直接返回

3、所有case都没有准备好,而且没有default

(1)将当前的goroutine加入到所有channel的等待队列(2)将当前协程转入阻塞,等待被唤醒

4、唤醒之后,返回channel对应的case index

5、select总结

(1)select语句中除了default之外,每个case操作一个channel,要么读要么写

(2)除default之外,各个case执行顺序是随机的

全站分卷索引 · 29 卷
  1. 1代码随想录知识星球精华(最强八股文)第五版(Go篇))
  2. 2Go string 和 []byte 的区别
  3. 3数组和切片的区别
  4. 4扩容前后的Slice是一样的吗
  5. 5Go语言map是有序的还是无序的, 为什么
  6. 6go里面的map是并发安全的吗?如何并发安全
  7. 7Go 的错误处理和 Java 的异常处理对比
  8. 8介绍一下panic和recover
  9. 9什么是defer?有什么作用
  10. 10Go并发
  11. 11进程、线程的区别
  12. 12什么是go runtine
  13. 13Go语言中的Channel是什么, 有哪些用途,如何处理阻塞
  14. 14什么是互斥锁(mutex)?在什么情况下会用到它们?
  15. 15Mutex有几种模式
  16. 16goroutine什么情况会发生内存泄漏?如何避免。
  17. 17Go语言中GC的流程是什么
  18. 18Go 中的内存逃逸现象是什么?
  19. 19CAP 理论,为什么不能同时满足
  20. 20说一下 Gin 的路由怎么实现的
  21. 21简述slice的底层原理,和数组的区别是什么
  22. 22defer底层原理
  23. 23侵入式和非侵入式的区别
  24. 24goroutine与线程的区别
  25. 25goroutine在什么情况下会被挂起呢?
  26. 26GC(垃圾回收)原理 1.5版本
  27. 27简述Go的垃圾回收机制
  28. 28协程优势及其通信方式
  29. 29Go的内存对齐