这是我参与【第五届青训营】伴学笔记创作活动的第4天,
性能优化:提高软件处理能力,减少不必要的消耗,为了让用户体验上升,同时资源高效利用,提高效率。
性能优化层次:
- 业务层优化(具体问题具体分析)
- 语言运行时优化 优化Go语言底层SDK时,这种优化适用于大面积,优化的时候要注意要确保之前的接口稳定;使用更多的测试用例,测试驱动开发;明确做了什么和没有做什么;要有隔离性,常用的是用选项控制是否开启优化;要有可观测性。
Go语言优化
- 内存管理优化
- 编译器优化
自动内存管理
垃圾回收:程序语言运行时系统动态管理内存(避免手动,提供安全性和正确性)
GC的三个任务:
- 为新对象分配空间
- 找到存活对象
- 回收死亡对象的内存空间
相关概率
Collectors必须感知对象指向关系的改变。
评价GC算法:安全性、吞吐率、暂停时间、内存开销
GC的两种技术
追踪垃圾回收
指针指向关系不可达时就可以回收了
步骤:先标记根对象,然后再标记可达的对象,最后清理不可达的对象。
分代GC:年轻代和老年代
引用技术
每一个对象都有一个关联的引入数目,当对象大于零时表示活着。
优点:操作被平摊到程序执行过程。
缺点:维护起来开销比较大;没有办法回收环形数据结构;内存开销;回收的时候可能引发暂停。
Go内存管理机制
Go内存分配:提取把内存分成小块,然后根据对象的大小选择合适的块。
Go内存缓存:多层缓存,帮助我们更快的分配内存
Go内存管理优化:对象分配是高频的,尤其是小对象,相对应的提出了Balanced GC,每一个g分配1KB内存,然后使用指针维护:base、end、top,top进行分配,在这种优化下面有可能存在一个小内存使得整个GAB延迟释放,针对这种情况,提出了移动GAB中存活的对象,本质上是使用copying GC算法管理小对象
编译器和静态分析
编译器:重要的系统软件,识别符合的语法和非法的程序,生成高效的代码。
编译器典型结构
静态分析:不执行程序代码,推导程序的行为,分析程序的性质
Go编译器优化
函数内联
将被调用函数体的副本替换到调用位置上,同时重写代码以反映参数的绑定。
优点:
- 减小开销
- 将过程间分析变成过程内分析
逃逸分析
分析代码中指针的动态作用域:指针在何处可以被访问