这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
1.自动内存管理
1.1 概念
动态内存:程序在运行时根据需求动态分配的内存:malloc()
自动内存管理(垃圾回收):
由程序语言的运行时系统管理动态内存
- Mutator:业务线程,分配新对象,修改对象指向关系
- Collector:GC线程,找到存活对象,回收死亡对象的内存空间
- Serial GC:collector
- Parallel GC:支持多个collectors同时回收的GC算法
- Concurrent GC:mutator(s)和collector可以同时执行,Collectors必须感知对象指向关系的改变!
评价GC算法
1.2 追踪垃圾回收
对象被回收的条件:
指针指向关系不可达的对象
标记根对象:
静态变量、全局变量、常量
线程栈等
标记:
找到可达对象
清理:
所有不可达对象
1.3 分代GC
- 分代假说:most objects die young
- Intution:很多对象在分配出来后很快就不再使用了
- 每个对象都有年龄:经历过GC的次数
- 目的:对年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销
- 不同年龄的对象处于heap的不同区域
年轻代
- 常规的对象分配
- 由于存活对象很少,可以采用copying collection
- GC吞吐率很高
老年代
- 对象趋于一直活着,反复复制开销较大
- 可以采用mark-sweep collection
1.4 引用计数
2. 内存管理及优化
2.1 Go内存分配——分块
目标:
为对象在heap上分配内存
提前将内存分块:
- 调用系统调用mmapO向OS申请一大块内存,例如4 MB·先将内存划分成大块,例如8 KB,称作mspan
- 再将大块继续划分成特定大小的小块,用于对象分配
- noscan mspan:分配不包含指针的对象——GC不需要扫描
- scan mspan:分配包含指针的对象——GC需要扫描
对象分配: 根据对象的大小,选择最合适的块返回
2.2 Go内存分配——缓存
- TCMalloc: thread caching
- 每个p包含一个mcache用于快速分配,用于为绑定于p上的g分配对象
- mcache管理一组mspan
- 当mcache 中的mspan分配完毕,向mcentral申请带有未分配块的mspan
- 当mspan中没有分配的对象,mspan会被缓存在mcentral 中,而不是立刻释放并归还给OS
2.3 Balanced GC
3. 编译器和静态分析
3.1 编译器的结构
3.1 静态分析
- 静态分析:不执行程序代码,推导程序的行为
- 控制流:程序执行流上的传递
- 数据流:数据在控制流上的传递
- 通过分析控制流和数据流,我们可以知道更多关于程序的性质
- 根据这些性质优化代码