这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
1.性能优化
由于自顶向下的是业务代码、SDK、基础库、语言运行时以及OS,所以性能优化有着针对不同层面的优化。
(1)业务层优化
针对特定场景,具体问题,具体分析
容易获得较大的性能收益
(2)语言运行时优化
解决更通用的性能问题
考虑更多场景
(3)数据驱动
自动化性能分析工具——pprof
依靠数据而非猜测,实事求是
首先优化最大瓶颈
2.自动内存管理
(1)概念
动态内存:程序在运行时根据需求动态分配的内存:类似于C语言的malloc()
自动内存管理:由程序语言的运行时系统管理动态内存
(2)追踪垃圾回收
对象被回收的条件:指针指向关系不可达的对象
(3)分代GC
分代假说:most objects die young
每个对象都有年龄:经历过GC的次数
目的:对年轻和老年的对象,指定不同的GC策略,降低整个提内存管理的开销
不同年龄的对象处于heap的不同区域
年轻代:常规的内存分配,由于存活对象很少,可以采用copying GC,GC吞吐率很高
老年代:对象趋向于一直活着,反复复制开销较大,可以采用mark-sweep GC
(4)引用计数
每个对象都有一个与之关联的引用数目
3.内存管理及优化
(1)分块
提前为对象在heap上分配内存
(2)缓存
TCMalloc:thread caching
缓存过程:每个p包含一个mcache用于快速分配,用于g分配对象,mcache管理一组mspan,当mcache中的mspan分配完毕,向mcentral的mspan,当mspan中没有分配的对象,mspan会被缓存在mcentral中
(3)内存管理优化
对象分配是非常高频的操作:每秒分配GB级别的内存
空间较小的对象占比比较高
Go内存分配比较耗时
4.静态分析
(1)控制流和数据流
静态分析 :不执行程序代码,推导程序的行为,分析程序的性质。
控制流:程序执行*流程
数据流:数据在控制流上的传递
(2)过程内分析
仅在函数内部进行分析
(3)过程间分析
考虑过程调用时参数传递和返回值的数据流和控制流
5.编译器优化
(1)思路
场景:面向后端长期执行任务
Tradeoff:用编译时间换取更高效的机器码
(2)函数内联
将被调用函数的函数体(callee)的副本替换到调用位置(caller)上,同时重写代码以反映参数的绑定
(3)Beast Mode
调整函数内联的策略,使更多函数被内联
降低函数调用的开销
增加了其他优化机会:逃逸分析