Go 语言内存管理 |青训营笔记

71 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
这是我参与「第五届青训营 」的第 6 天

自动内存管理
Go 内存管理及优化
编译器和静态分析
Go 编译器优化

引言

什么是性能优化?

  • 提升软件系统处理能力,减少不必要的消耗,充分发掘计算机算力

为什么要做性能优化?

  • 用户体验:带来用户体验的提升 —— 让刷抖音更丝滑,让双十一购物不再卡顿
  • 资源高效利用:降低成本,提高效率 —— 很小的优化乘以海量机器会是显著的性能提升和成本节约

性能优化的层面

业务层优化

  • 针对特定场景,具体问题,具体分析
  • 容易获得较大性能收益

语言运行时优化

  • 解决更通用的性能问题
  • 考虑更多场景
  • Tradeoffs

数据驱动

  • 自动化性能分析工具 —— pprof
  • 依靠数据而非猜测
  • 首先优化最大瓶颈

软件质量

  • 软件质量至关重要
  • 保证接口稳定的前提下改进实现
  • 测试驱动:测试用例覆盖尽可能多的场景,方便回归
  • 文档:通过清晰的文档告诉用户这一项优化做了什么,没做什么,能达到怎样的效果
  • 隔离:优化代码用选项和原先的路径隔离,保证优化未启用时的行为同以前一致
  • 可观测(必要的日志输出)、可灰度、可回滚

自动内存管理

基本概念

动态内存

  • 程序在运行时根据需求动态分配的内存:malloc()

自动内存管理(垃圾回收)

  • 避免手动内存管理,专注于实现业务逻辑
  • 保证内存使用的正确性和安全性: double-free problem, use-after-free problem

三个任务

  • 为新对象分配空间
  • 找到存活对象
  • 回收死亡对象的内存空间

相关概念

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

image.png

Serial GC 算法

  • 会有暂停
  • 只有一个collector

Parallel GC 算法

  • 并行GC,支持多个collectors同时回收的GC算法
  • 性能比Serial GC高一些

Concurrent GC

  • 并发GC,支持mutator(s)collector(s)同时执行的GC算法
  • 不用显示的暂停程序,需要时把collector(s)唤醒,一边做垃圾回收一边用户线程还在执行着,等到GC做完后,再把其休眠掉,接着mutator(s)又可以同步进行了

  • 挑战:Collectors 必须感知对象指向关系的改

评价GC算法

  • 安全性(Safety):不能回收存活的对象 基本要求
  • 吞吐率(Throughput):1GC时间程序执行总时间1-\frac{GC时间}{程序执行总时间} 花在GC上的时间(花在GC上的时间越少越好,所以吞吐量越大越好)
  • 暂停时间(Pause time):stop the world(STW) 业务是否感知(暂停时间越短越好)
  • 内存开销(Space overheadGC元数据开销

追踪垃圾回收(Traing garbage collection) image.png

  • copying GC image.png
  • Mark-sweep GC image.png
  • Compact GC image.png

分代GC image.png image.png

引用计数(Reference counting) image.png

Go内存管理及优化

  • 目标:为对象在heap上分配内存
  • 提前将内存分块

image.png

image.png

image.png

Balanced GC image.png

image.png

编译器和静态分析