Go内存分配
分块
目标: 为对象在heap上分配内存 提前将内存分块:调用系统调用mmap()向OS申请一大块内存,先将内存划分成大块,再将大块继续划分成特定大小的小块 对象分配:根据对象的大小,选择最合适的块返回
缓存
- TCMalloc
- mcache管理一组mspan
- 当mcache中的mspan分配完毕,向mcentral申请带有未分配块的mspan
内存管理优化
- 对象分配:每秒分配GB级别的内存
- 小对象占比高
- go内存分配比较耗时
Balanced GC
- 指针碰撞风格的对象分配
- 实现了copying GC
- 性能收益
编译器和静态分析
编译器
- 词法分析,生成词素
- 语法分析,生成语法树
- 语义分析,收集类型信息,进行语义检查
- 中间代码生成
静态分析
不执行程序代码,推导程序行为,分析程序的性质
- 控制流:程序执行的流程
- 数据流:数据在控制流上的传递
过程内分析和过程间分析
- 过程内分析:仅在函数内部进行分析
- 过程间分析:考虑函数调用时参数传递和返回值的数据流和控制流
Go编译器优化
Beast Mode 提升代码性能
函数内联
将被调用函数的函数体的副本替换到调用位置上,同时重写代码以反映参数的绑定
优点:
- 消除函数调用开销
- 将过程间分析转化为过程内分析
缺点:
- 函数体变大
- 编译生成的go镜像变大
函数内联在大多数情况下是正向优化
逃逸分析
分析代码中指针的动态作用域:指针在何处可以被访问
优化:未逃逸的对象可以在栈上分配
- 对象在栈上分配和回收很快
- 减少在heap上的分配,降低GC负担