这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记,如有错误还请指正。 【有船启航】
下篇主要是Go语言的优化。
- 自动内存管理(垃圾回收) 管理的是动态内存,由程序语言的运行时系统管理动态内存:避免手动内存管理,专注于业务逻辑;保证内存使用的正确性和安全性。 名词解释:
-
Mutator:业务线程,分配新对象,修改对象指向关系
-
Collector:GC线程,找到存活对象,回收死亡对象的内存空间
-
Serial GC:只有一个collector
-
Parallel GC:支持多个collector同时回收的GC算法
-
Concurrent GC:mutator和collector可同时执行 GC算法的评价指标:安全性、吞吐率、暂停时间、内存开销
- GC (Tracing garbage collection)
- Generational GC
- Reference counting
-
Go内存管理机制及优化
- noscan 不包含指针的对象
-
编译器和静态分析
- 静态分析:
- 静态分析:不执行程序代码,推导程序的行为,分析程序的性质。
- 控制流(Control flow):程序执行的流程
- 数据流(Data flow):数据在控制流上的传递
- 通过分析控制流和数据流,我们可以知道更多关于程序的性质(properties)
- 数据流分析和控制流分析: 过程内分析和过程间分析:过程间分析往往需要同时分析控制流和数据流,联合求解,比较复杂。
- 静态分析:
-
Go编译器优化思路 函数内联、逃逸分析、默认栈大小调整、边界检查消除、循环展开……
-
函数内联:
-
内联:将被调用函数的函数体(callee)的副本替换到调用位置(caller)上,同时重写代码以反映参数的绑定
-
优点:
- 消除函数调用开销,例技传递参数,保存奇存器等。
- 将过程间分析转化为过程内分析,帮助其他优化,例如逃逸分析。
-
缺点:
- 函数体变大,instruction cache (icache)不友好
- 编译生成的Go镜像变大
-
内联策略
-
-
Beast Mode
-
Go函数内联受到的限制较多:
- 语言特性,例如interface, defer等,限制了函数内联
- 内联策略非常保守
-
Beast mode:调整函数内联的策略,使更多函数被内联
- 降低函数调用的开销
- 增加了其他优化的机会:逃逸分析
-
开销
- Go镜像增加~10%
- 编译时间增加
-
-
逃逸分析:分析代码中指针的动态作用域:指针在何处可以被访问
-
大致思路
-
从对象分配处出发,沿着控制流,观察对象的数据流
-
若发现指针p在当前作用域s:
- 作为参数传递给其他函数·传递给全局变量
- 传递给其他的goroutine
- 传递给已逃逸的指针指向的对象
-
则指针p指向的对象逃逸出s,反之则没有逃逸出s
-
-
Beast mode:函数内联拓展了函数边界,更多对象不逃逸
-
优化:未逃逸的对象可以在栈上分配
- 对象在栈上分配和回收很快:移动sp
- 减少在heap 上的分配,降低,GC负担
-
-
\