Go上手笔记(三) 优化下篇| 青训营笔记

96 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记,如有错误还请指正。 【有船启航】

下篇主要是Go语言的优化。

  1. 自动内存管理(垃圾回收) 管理的是动态内存,由程序语言的运行时系统管理动态内存:避免手动内存管理,专注于业务逻辑;保证内存使用的正确性和安全性。 名词解释:
  • Mutator:业务线程,分配新对象,修改对象指向关系

  • Collector:GC线程,找到存活对象,回收死亡对象的内存空间

  • Serial GC:只有一个collector

  • Parallel GC:支持多个collector同时回收的GC算法

  • Concurrent GC:mutator和collector可同时执行 GC算法的评价指标:安全性、吞吐率、暂停时间、内存开销

    • GC (Tracing garbage collection)
    • Generational GC
    • Reference counting
  1. Go内存管理机制及优化

    • noscan 不包含指针的对象
  2. 编译器和静态分析

    1. 静态分析:
      • 静态分析:不执行程序代码,推导程序的行为,分析程序的性质。
      • 控制流(Control flow):程序执行的流程
      • 数据流(Data flow):数据在控制流上的传递
      • 通过分析控制流和数据流,我们可以知道更多关于程序的性质(properties)
      • 数据流分析和控制流分析: 过程内分析和过程间分析:过程间分析往往需要同时分析控制流和数据流,联合求解,比较复杂。
  3. Go编译器优化思路 函数内联、逃逸分析、默认栈大小调整、边界检查消除、循环展开……

    1. 函数内联:

      • 内联:将被调用函数的函数体(callee)的副本替换到调用位置(caller)上,同时重写代码以反映参数的绑定

      • 优点:

        • 消除函数调用开销,例技传递参数,保存奇存器等。
        • 将过程间分析转化为过程内分析,帮助其他优化,例如逃逸分析。
      • 缺点:

        • 函数体变大,instruction cache (icache)不友好
        • 编译生成的Go镜像变大
      • 内联策略

    2. Beast Mode

      • Go函数内联受到的限制较多:

        • 语言特性,例如interface, defer等,限制了函数内联
        • 内联策略非常保守
      • Beast mode:调整函数内联的策略,使更多函数被内联

        • 降低函数调用的开销
        • 增加了其他优化的机会:逃逸分析
      • 开销

        • Go镜像增加~10%
        • 编译时间增加
    3. 逃逸分析:分析代码中指针的动态作用域:指针在何处可以被访问

      • 大致思路

        • 从对象分配处出发,沿着控制流,观察对象的数据流

        • 若发现指针p在当前作用域s:

          • 作为参数传递给其他函数·传递给全局变量
          • 传递给其他的goroutine
          • 传递给已逃逸的指针指向的对象
        • 则指针p指向的对象逃逸出s,反之则没有逃逸出s

      • Beast mode:函数内联拓展了函数边界,更多对象不逃逸

      • 优化:未逃逸的对象可以在栈上分配

        • 对象在栈上分配和回收很快:移动sp
        • 减少在heap 上的分配,降低,GC负担

\