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

100 阅读2分钟

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

go内存管理机制及内存管理优化

2.1 go内存分配

  • 分块 为对象在heap上分配内存,先提前申请一块大内存,在分成多块小内存,根据对象的大小分配最合适的块返回
  • 缓存 p包含mcache为绑定于p上的g分配内存,mcache管理一组mspan,mspan中没有空闲位置时,会向mcentral申请一块未分配的mspan,当一块mspan空时,不会立即释放,而是被缓存到mcentral中 image.png

Balanced GC

  • GAB:每个g都绑定一大块内存。用于noscan类的内存分配 用base,top,end三个指针维护 image.png

GAB对go内存管理是一个对象,优化的本质是将分配多个小对象转化为分配一个对象,当一个gab总大小小于一个阈值时,将其中存活的对象分配到其他gab中,并且可以考虑释放此gab的内存避免内存泄漏。

3. 编译器和静态分析

3.1编译器的结构

1.重要的系统软件

  • 识别符合语法和非法的程序,生成正确且高效的代码 2.分析部分(前端) 3.综合部分(后端) image.png

3.2静态分析

定义:不运行程序代码,推导代码的行为
控制流:程序执行的流程
数据流:数据在控制流上的传递
通过分析控制流和数据流确定程序的性质以便优化

3.3过程内分析和过程间分析

前者仅在函数内部分析,后者需要考虑函数调用时传递参数和返回值的控制流和数据流,较为复杂。

4. go编译器优化的基本问题与思路

4.1优化操作

1. 函数内联
对于轻量代码,使用函数内联可以将过程间分析转化为过程内分析,属于正向优化

Beast Mode

调整函数内联的策略,使更多函数被内联,减少函数调用的开销
2. 逃逸分析
分析代码中指针的作用域。从对象分配处沿着控制流,观察对象的数据流。 指针逃逸出当前作用域的原因:
1.作为参数被函数调用
2.传递给全局变量或 goroutine
3.传递给已经逃逸的指针指向的对象

Beast Mode

函数内联拓展函数边界,减少逃逸
未逃逸的对象可以在栈上进行操作,减少在heap上的分配,降低GC负担