简述Go的垃圾回收机制
简述Go的垃圾回收机制
go目前使用的垃圾回收机制是三色标记法配合写屏障和辅助GC
三色标记法是对标记回收算法的改进:
- 初始阶段所有对象都是白色
- 从root根出发扫描根对象,将它们引用到的对象都标记为灰色,其中root区域主要是当前程序运行到的栈和全局
数据区域,是实时使用到的内存
- 将灰色对象标记为黑色,分析该灰色对象是否引用了其他对象,如果有引用其他对象,就将引用的对象标记为灰色
- 不断分析灰色对象,直到灰色对象队列为空,此时白色对象即为垃圾,进行回收
在内存管理中,allocBits记录了每块内存的分配情况,而gcmarkBits记录了每块内存的回收标记情况,在标记阶段会对每块内存进行标记,有对象引用的标记为1,没有的标记为0,结束标记后,将allocBits指向gcmarkBits,则有标记的才是
存活的内存块,这样就完成了内存回收
进行垃圾回收需要进行STW,如果STW时间过长对于应用执行来说是灾难性的,因此为了缩短STW的时间,golang引入了写屏障和辅助GC
写屏障是让GC和应用程序并发执行的手段,可以有效减少STW的时间
辅助GC是为了防止GC过程中内存分配的速度过快,因此会在GC过程中让mutator线程并发执行,协助GC执行一部分回收工作
GC触发机制有:
- 内存分配量达到阈值:每次内存分配前都会检查当前内存分配量是否达到阈值,如果达到则触发GC, 阈值=上次
GC时的内存分配量 * 内存增长率
- 定时触发GC:默认情况下两分钟触发一次GC,可由runtime中的参数声明
- 手动触发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代码随想录知识星球精华(最强八股文)第五版(Go篇))
- 2Go string 和 []byte 的区别
- 3数组和切片的区别
- 4扩容前后的Slice是一样的吗
- 5Go语言map是有序的还是无序的, 为什么
- 6go里面的map是并发安全的吗?如何并发安全
- 7Go 的错误处理和 Java 的异常处理对比
- 8介绍一下panic和recover
- 9什么是defer?有什么作用
- 10Go并发
- 11进程、线程的区别
- 12什么是go runtine
- 13Go语言中的Channel是什么, 有哪些用途,如何处理阻塞
- 14什么是互斥锁(mutex)?在什么情况下会用到它们?
- 15Mutex有几种模式
- 16goroutine什么情况会发生内存泄漏?如何避免。
- 17Go语言中GC的流程是什么
- 18Go 中的内存逃逸现象是什么?
- 19CAP 理论,为什么不能同时满足
- 20说一下 Gin 的路由怎么实现的
- 21简述slice的底层原理,和数组的区别是什么
- 22defer底层原理
- 23侵入式和非侵入式的区别
- 24goroutine与线程的区别
- 25goroutine在什么情况下会被挂起呢?
- 26GC(垃圾回收)原理 1.5版本
- 27简述Go的垃圾回收机制
- 28协程优势及其通信方式
- 29Go的内存对齐