高性能 Go 语言发行版优化与落地实践 | 青训营笔记

1,324 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记。

一、自动内存管理

1.1 概念

动态内存:程序在运行时根据需求动态分配内存
自动内存管理(垃圾管理):由程序的运行时系统管理动态内存
三个任务

  • 为新对象分配空间
  • 找到存活对象
  • 回收死亡对象的内存空间
    自动内存管理-相关概念 image.png
  • GC算法指标 image.png
  • 追踪垃圾回收 image.png
  • 分代GC image.png
  • 引用计数的优缺点 image.png

二、Go内存管理及优化

2.1 Go内存分配

2.1.1 分块

目标:为对象在heap上分配内存
分成的块称作mspan
mspan类型
GC不需要扫描:noscan mspan:分配不包含指针的对象
GC需要扫描:scan mspan:分配包含指针的对象
注:根据对象的大小,选择最合适的块返回

2.1.2 缓存

image.png

2.2 Go内存管理优化

  • 对象分配是非常高频的操作:每秒分配GB级别的内存
  • 小对象占比较高
  • Go内存分配比较耗时 有一个路径g->m->p->...
    (mallocgc:用于对象分配内存) Banlanced GC

总结

image.png

三、编译器和静态分析

3.1 基本介绍

image.png

3.2 数据流和控制流

image.png

3.3 过程内和过程间分析

过程内分析:仅在函数内部进行分析
过程间分析:考虑函数调用时参数传递和返回值的数据流和控制流

四、GO编译器优化

编译优化的思路:

  • 场景:面向后端长期执行任务
  • Tradeoff:用编译时间换取更高效的机器码

4.1 函数内联

内联:将被调用函数的函数体的副本替换到调用位置上,同时重写代码以反映参数的绑定。
优点:

  • 消除函数调用开销,例如传递参数
  • 过程间分析转化为过程内分析,帮助其他优化,例如逃逸分析 缺点:
  • 函数体变大
  • 编译生成的Go的镜像变大
    函数内联在大多数情况下是正向优化
    内联策略
    ...

4.2 逃逸分析

逃逸分析:分析代码中指针的动态作用域:指针在何处可以被访问
Beast Mode:函数内联拓展了函数边界,更多对象不逃逸
优化:未逃逸的对象可以在栈上分配

  • 对象在栈上分配和回收很快:移动sp
  • 减少在heap上的分配,降低GC负担

五、课程总结

高性能Go语言发行版优化与落地实践
性能优化:

  • 自动内存管理
  • Go内存管理
  • 编译器与静态分析
  • 编译器优化

实践:

  • Banlanced GC 优化对象分配
  • Beast Mode提升代码性能

分析问题的解决方法与解决问题的思路,不仅适用于Go语言,其他的语言优化也同样适用。

六、参考文献

image.png