Go性能优化
该部分内容也是边听边记的内容,比较简洁,更相当于一个概述,每块内容都还可以查阅资料,进行更深度的学习,这也是青训营的好处————告诉你有哪些东西是需要学的,然后可以根据自己兴趣和需要去深入学习。
-
性能调优实战
-
简介
- 原则:1.要依靠数据而不是猜测;2.要定位最大瓶颈而不是细枝末节;3.不要过早优化;4.不要过度优化
-
性能分析工具pprof实战:用于可视化和分析性能分析数据的工具
-
pprof采样过程和原理:
- CPU:启动定时器,操作系统每隔10ms向进程发送一次SIGPROF信号,然后进程接收到信号后记录调用堆栈,每100ms读取已经记录好的调用栈并写入输出流
- Heap:采样程序通过内存分配器在堆上分配和释放的内存,记录分配/释放的大小和数量,每512KB记录一次
- Goroutine:记录所有用户发起的且在运行中的goroutine runtime.main的调用栈信息
- ThreadCreate:记录程序创建的所有系统线程的信息
- Block:采样阻塞操作的次数和耗时,可以设置采样率
- Mutex:采样竞争锁的次数和耗时
-
性能调优案例
- 业务服务优化:单benchmark无法满足复杂逻辑分析、请求流量构造、压测、性能数据采集。正确性是基础!!!
- 基础库优化
- Go语言优化
-
高性能Go语言发行版优化与落地实践
-
数据驱动优化
-
背景
-
自动内存管理
- 概念:mutator:业务线程,分配新对象;Collector:GC线程;Serial GC:只有一个Collector;Parallel GC:支持多个Collectors;Concurrent GC:mutators和collectors可以同时执行,collectors必须正确感知对象指向关系的改变
- Tracing garbage collection:标记根对象-标记-清理(分策略)
- Generational GC:分代GC,不同对象不同的GC策略
- Reference Counting:引用计数;优点:内存管理的操作被平摊到程序执行过程中;内存管理不需要了解runtime的实现细节:c++智能指针;缺点:维护开销更大,无法回收环形数据结构,回收时仍然可能引发暂停
-
Go内存管理机制
-
Go内存分配:1.提前将内存分块 mspan;2.缓存 TCMalloc:thread caching,多层缓存,mcache、mcentral;
-
Go内存分配优化
- 字节的优化方案:Balanced GC:每个Goroutine绑定一大块内存:goroutine allocation buffer(GAB),用于 noscan类型的小对象分配,使用三个指针维护GAB,指针碰撞(Bump pointer)风格的对象分配。GAB对于Go内存管理来说是一个大对象,本质是将多个小对象的分配合成一次大对象的分配,问题:GAB的对象分配形式会延迟内存的释放——方法:移动GAB中存活的对象,用copying GC的算法管理小对象
-
-
编译器和静态分析
- 基本介绍:编译器结构和编译器后端优化
- 数据流和控制流
- 过程内和过程间分析
-
编译器优化的基本问题和思路
- 函数内联 Inlining:优点:消除函数调用开销;将过程间分析转化为过程内分析,帮助其他优化,比如逃逸分析
- 逃逸分析:分析代码中指针的动态作用域;内联会导致逃逸分析减少,从而完成栈上分配
-