这是我参与「第三届青训营 -后端场」笔记创作活动的的第2篇笔记。
引:性能优化的层面
1.业务代码:处理用户请求
2.SDK
3.基础库
SDK和基础库:指高性能数据结构,网络库,IO库
4.语言运行时:指GC,调度器
5.OS:提供合理的运行时环境
引:性能优化与软件质量
隔离:区分优化和不优化(用户有选择是否优化的权力)
可观测:通过日志输出,观测优化与不优化的性能差异
自动内存管理
相关概念
--Mutator:用户启动的goroutine就是一个Mutator
追踪垃圾回收
有关联、还会调用的对象就会被标记,进而清除未被标记的对象。
根据对象的生命周期,使用不同的标记和清理策略,可以提高回收效率。
分代GC(Generational GC)
引用计数
--weak reference解决无法回收环形数据结构问题
内存管理优化
[对象分配]是非常高频的操作:每秒分配GB级别的内存 且对[小对象]的分配占比比较高,即我们大多数时候都是在做对小对象的内存分配,而[Go的内存分配比较耗时(分配路径长:g->m->p->mcache->mspan->memory block->return pointer)],高频的调用和较长的路径,导致占用了很高的CPU。
字节的优化方案Balanced GC[针对堆上的分配]
相当于为小对象分配时先预分配一个空间,对其他小对象分配内存时进行多次指针调用,都将其装入预分配的空间。[相当于将多个小对象的分配合并成一次对大对象的分配]
---问题[GAB的对象分配方式会导致内存被延迟释放]
GAB中有一个小对象的存活就导致了整个GAB都是存活的,相当于这种情况下,一个小对象就会独自占用1KB的内存,导致内存被延迟释放。
编译器和静态分析
编译器的结构
--源代码:读入后成字符串的一个流
--IR:与机器无关。各种编译器都用同一个IR
因为IR是与机器无关的,所以代码优化也是与机器无关的
静态分析
Go编译器优化
因为编译器优化可以使用户无感知(即时效间隔短,不影响流畅程度),且通用性强,一个地方的优化可以令使用这部分的所有对象都得到优化。