Go性能优化 | 青训营笔记

75 阅读3分钟

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:优点:消除函数调用开销;将过程间分析转化为过程内分析,帮助其他优化,比如逃逸分析
      • 逃逸分析:分析代码中指针的动态作用域;内联会导致逃逸分析减少,从而完成栈上分配