这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
性能优化层面
- 业务优化
- 针对特定场景,具体问题,具体分析
- 容易获得较大性能收益
- 语言运行时优化
- 解决更通用的性能问题
- 考虑更多场景
- Tradeoffs
- 数据驱动
- 自动化性能分析工具 - pprof
- 依靠数据而非猜测
- 首先优化最大瓶颈
性能优化与软件质量
- 软件质量至关重要
- 在保证接口稳定的前提下改进具体实现
- 测试用例: 覆盖尽可能多的场景,方便回归
- 文档: 做了什么,没做什么,能达到怎样的效果
- 隔离: 通过选项控制是否开启优化
- 可观测: 必要的日志输出
自动内存管理(垃圾回收)
概念
- Mutator: 业务线程,分配新对象,修改对象指向关系
- Collector: GC 线程,找到存活对象,回收死亡对象的内存空间
- Serial GC: 只有一个 collector
- Parallel GC: 支持多个 collectors 同时回收的 GC 算法
- Concurrent GC: mutator(s) 和 collector(s) 可以同时执行
追踪垃圾回收
- 被回收条件:指针指向关系不可达对象
- 标记根对象
- 标记:找到可达对象
- 清理:所有不可达对象
- Copying GC:将存活对象复制到另外的内存空间
- Mark-sweep GC:将死亡对象的内存标记为可分配
- Mark-compact GC:将存活对象移动到最左边
- 分代GC:对年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销
- 年轻对象:存活对象少,一般用 Copying GC
- 老年对象:趋于一直或者,一般采用 Mark-sweep GC
引用计数
- 优点:内存管理的操作被平摊到程序执行过程中
- 缺点:(巴拉巴拉一大堆😒)开销大,可能引发暂停
内存管理级优化
Go内存分配 - 分块
- 提前将内存分块,根据对象的大小,选择最合适的块返回
Go内存管理分配 - 缓存
Go内存管理优化
- Balanced GC
- 将多个小对象的分配合并成一次大对象的分配
- 本质:用Copying GC 管理小对象
编译器和静态分析
静态分析
- 静态分析:不执行程序代码,推导程序行为
- 控制流:程序执行的流程
- 数据流:数据在控制流上的传递
- 过程内分析:函数内部
- 过程间分析:考虑过程调用时参数的传递和返回值的数据流和控制流
编译器优化
- 函数内联
- Beast Mode
函数内联拓展了函数边界,更多对象不逃逸
- 逃逸分析
- 逃逸分析