这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
一、本堂课重点内容:
- 自动内存管理
- Go内存管理及优化
- 编译器和静态分析
- Go编译器优化
二、详细知识点介绍:
相关术语解读
自动内存管理
-
Auto memory management: 自动内存管理
-
Grabage collction: 垃圾回收
-
Mutator: 业务线程,分配新对象,修改对象指向关系(用户启动的现场)
-
Collector: GC 线程,找到存活对象,回收死亡对象的空间
-
Serial GC:只有一个Collector
-
Concurrent GC: 并发 GC,Mutator(s)和Collector(s)可以同时执行 (collectors必须感知对象指向关系的转变)
-
Parallel GC: 并行 GC,支持多个collectors同时回收的GC算法
-
Tracing garbage collection: 追踪垃圾回收
- Copying GC: 复制对象 GC
- Mark-sweep GC: 标记-清理 GC
- Mark-compact GC: 标记-压缩 GC
-
Reference counting: 引用计数
-
Generational GC: 分代 GC
- Young generation: 年轻代
- Old generation: 老年代
Go 内存管理及优化
- TCMalloc
mmap()系统调用- scan object 和 noscan object
- mspan, mcache, mentral
- Bump-pointer object allocation: 指针碰撞风格的对象分配
编译器和静态分析
- 词法分析
- 语法分析
- 语义分析
- Intermediate representation (IR) 中间表示
- 代码优化
- 代码生成
- Control flow: 控制流
- Data flow: 数据流
- Intra-procedural analysis 过程内分析
- Inter-procedural analysis: 过程间分析
Go 编译器优化
- Function inlining: 函数内联
- Escape analysis: 逃逸分析
性能优化局面
-
业务层优化针对特定场景
-
语言运行时优化解决更加通用的问题
自动内存管理
作用
- 为新对象分配空间
- 找到存活对象
- 回收死亡对象的空间
追踪垃圾回收
基本原理
- 对象被回收的条件:制作指向关系不可达的对象
从标记的根对象找到可达的对象,然后清理不可达对象
- Copying GC:将存活对象复制到另外的内存空间
- Mark-sweep GC:将死亡对象的内存标记为“可分配”
- Mark-compact GC:一定并整理存活对象
注意:根据对象的生命周期,使用不同的标记和清理策略
分代GC
引用计数
- 每个对象都有一个与之关联的引用数目
-
对象存活的条件:当且仅当引用数大于0
-
优点:
- 内存管理的操作被平摊到程序执行过程中
- 内存管理不需要了解runtime的实现细节,例如c++的智能指针
-
缺点:
- 维护引用计数的开销较大,通过原子操作保证对引用计数操作的原子性和可见性
- 无法回收环形数据结构,例如weak reference可以解决
- 内存开销较大:存储引用计数
- 回收内存时依然可能引发暂停,例如回收一个很大的节点
三、课后个人总结:
学习了Go相关内存管理的知识,对Go的内存管理及优化有了一个初步的认识