go的GC
Go的协程栈的位置
Go的协程栈位于Go的堆内存上
Go堆内存位于操作系统的虚拟内存上
协程栈记录了协程的执行现场
协程栈负责记录局部变量,传递参数和返回值
Go使用参数拷贝传递
逃逸分析
逃逸分析是编译器在编译阶段对变量的生命周期进行分析,判断变量是在栈上还是堆上分配空间。逃逸分析的主要目的是优化内存的分配和减少垃圾回收的压力
栈帧回收后,需要继续使用的变量
变量太大了,栈里面放不下,放到堆里面去
指针逃逸
空接口逃逸
- 如果函数的参数位interface{}
- 函数的实参很可能会逃逸
- 因为interface{}类型的函数往往会使用反射
大变量逃逸
make && new
串行GC
Go使用 标记-删除 ,找到有引用的对象,剩下的就是没有引用的
GC-root是什么
- 被栈上的指针引用
- 被全局变量指针引用
- 被寄存器中的指针引用
- 上述为 GC-root
串行GC步骤
- stop the world,暂停所有其他协程
- 通过可达性分析,找到无用的堆内存
- 释放无用的堆内存
- 恢复所有其他协程
Mark Sweep的缺点
- STW,stop the world;让程序暂停,程序出现卡顿 **(重要问题)**;
- 标记需要扫描整个heap;
- 清除数据会产生heap碎片。
三色标记法
- 黑色:有用,已经分析扫描
- 灰色:有用,还未分析扫描
- 白色:暂时无用
混合屏障
删除屏障
- 并发标记时
- 对指针释放的白色对象置灰
防止释放的元素A被另一个元素B指向,但元素A被GC的情形
插入屏障
- 并发插入时
- 对插入的白色标记置灰
防止 新插入的元素被GC
GC的触发时机
系统定时触发
用户显示触发
申请内存时触发
GC的优化原则
- 尽量少在堆上产生垃圾
- 内存池化(类似channel的ring buffer)
- 减少内存逃逸
- 使用空结构体
GC的分析工具
- go tool pprof
- go tool trace
- go build -gcflags=” -m”
- GODEBUF=” gctrace=1”
go的GC
http://example.com/2024/02/25/go的GC/