5.14_Go性能优化 | 青训营笔记

117 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记。

篇幅

  • 性能优化
  • 自动内存管理
  • Go内存分配

性能优化

  • 减少计算消耗,提高软件处理能力。
  • 提升用户的体验,不用被冗长耗时的模块。
  • 在海量设备情况下,微小的优化也能得做到显著的性能提升和资源节省。

性能优化的两个层面

  • 基于数据驱动,采用性能分析工具,从最大的性能瓶颈模块开始优化。

业务层优化

  • 针对特性场景、具体问题的优化

语言运行时优化

  • 通用性能优化

性能优化的可维护性

  • 保证已实现接口的稳定性下进行改进
  • 测试用例的完整性
  • 隔离性,允许屏蔽优化,避免优化出现问题影响非优化用户
  • 完整的用户文档,覆盖模块功能的描述和使用效果
  • 必要日志输出记录

自动内存管理

自动内存管理(GC)是由程序语言的运行时系统回收动态内存,例如Java中是由JVM虚拟机对堆空间进行垃圾回收,主要完成3个任务:

  • 为新对象分配内存空间
  • 查找存活对象和年龄晋升
  • 回收死亡对象的内存空间

相关概念

基本概念

  • Mutator: 业务线程,分配新对象,修改对象指向关系
  • Collector: GC线程,寻找存货对象,回收死亡对象内存空间

GC分类

  • Serial GC: 单个Collector完成回收
  • Paraller GC: 多个Collectors同时回收
  • Concurrent GC: Mutators和Collectors同时执行

垃圾回收算法

  • 标记-清除 内存空间标记不需要的对象,统一回收-->内存碎片化
  • 标记-复制 将内存空间分为相同大小两部分,对象只存储在一半的空间,存活对象连续复制到另一半空间后,清理另一半空间。
  • 标记-整理 标记不要的对象,移动存活对象使它们连续。

可达性分析

GC的第一步需要判断哪些对象已经死亡

引用计数法

每个对象都有一个引用数目,当引用大于0时,存活。

  • 缺点
    • 对象互相循环引用不可用
    • 开销大,需要采用原子操作

GC Roots 可达性分析

从一个根对象开始向下搜索,形成引用链,当一个对象到达GC Roots不可达的时候,这个对象不可用,需要回收。

  • Root对象

静态变量、全局变量、常量、线程栈等

  • 常用算法 三色标记法(三色标记法因为由并发的性质,会产生浮动垃圾)

GO内存分配

分块

  • 系统调用mmap(),申请内存空间,例如4MB
  • 将内存分为固定大小的大块(mspan),例如8MB
  • 将大块分为特定大小的小块,例如8B,16B,24B
  • 根据对象的大小,选择合适的块返回

缓存

  • mcache本地缓存可用的mspan资源,供Goroutine分配,不消耗锁资源
  • mcentral为所有mcache提供mspan资源
  • mcache中分配完或没有特定大小的mspan时,就会从mcentral获取