这是我参与「第五届青训营」笔记创作活动的第1天。
自动内存管理
概念介绍
基础知识
- 业务线程(Mutator):分配新对象,修改对象指向关系
- Collector:GC 线程,找到存活对象,回收死亡对象
- 序列(Serial):Serial GC,只有一个 collector。收集时需要业务线程暂停。
- 并发(Concurrent):管理多任务的方式,仍然在一个处理器上运行。Concurrent GC,mutator 和 collector 同时进行
- 并行(Parallel):多个处理器同时运行多个任务。Parallel GC,支持多个 collector 同时回收。
垃圾回收
-
追踪垃圾回收(Tracing garbage collection):标记可达对象,清除不可达对象。清理方法如下:
- semi-space collector(coping):将内存空间均分为两部分,其中一部分达到容量上限时,触发垃圾回收,将可达对象复制到另一半空间

- mark and sweep:递归遍历可达对象(mark),遍历所有对象并清除不可达(sweep)
)
- mark and compact:相当于复制算法的改进版,降低了空间开销
-
引用计数:
- 给对象添加引用计数器,为 0 时即可清除。
- 优点:内存管理的操作被平摊到程序执行过程中。
- 缺点:开销大;环形结构无法回收;无法避免暂停
-
分代回收:
- 原理:大多数对象会夭折。
- 当新生代内存满时,可以使用复制算法清除。老年代满时,使用 mark-sweep 法清除。
Go 内存管理和优化
TCMalloc(Thread-Caching Malloc)
定长记录,不定长记录
- free list:用链表存储未分配内存,表头用于分配,表尾用于收集回收的内存。常用于定长记录
- 内存分块:将内存分块,给对象分配整数倍的块
mmap()(memory-mapped)
内存映射实现了虚拟内存,可以操作比内存更大的文件。或者实现从内核缓冲区到用户缓冲区的映射,减少上下文切换
func Map(f *os.File, prot, flags int) (MMap, error)
prot:映射的保护等级(读写权限)
flags:unix.MAP_SHARED,unix.MAP_PRIVATE,unix.MAP_ANON
课上-性能优化及自动内存管理
优化角度
-
业务层优化
-
语言运行时优化
-
数据驱动
- 使用性能分析工具-pprof
- 优先优化最大瓶颈
工作原则
- 测试用例覆盖面尽可能广
- 文档:已实现,未实现,效果
- 隔离:通过选项控制是否开启
- 可观测:输出日志
自动内存管理
优势
- 降低开发难度
- 保证内存使用安全性和正确性
评价指标
- 安全性:不回收存活对象
- 吞吐率:1-\frac{GC时间}{程序执行总时间},即花在GC上的时间
- 暂停时间
- 内存开销
编译器优化
函数内联
将 callee 的副本替换到 caller 位置上,同时重写代码反映参数的绑定
- 优点:消除调用开销;转化为过程内分析,方便其他优化
- 缺点:函数体变大,icache 不友好
Beast Mode
调整内联策略,内联更多函数