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

39 阅读2分钟

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

0.性能优化

性能优化是为了充分发掘计算机算力提升软件系统处理能力,减少不必要的消耗

为什么要做性能优化?

  • 带来用户体验的提升
  • 降低成本、提高效率

1.自动内存管理

动态内存:程序运行时根据需求动态分配的内存(如c++的malloc()函数) 自动内存管理:由程序语言的运行时系统管理动态内存
要实现自动内存管理要实现三个任务

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

评价一个GC算法的好坏有基本的四个标准:

  • 安全性:不能回收存活对象(基本要求
  • 吞吐量:1GC时间程序运行总时间1-\frac{GC时间}{程序运行总时间}花在GC上的时间
  • 暂停时间(业务是否感知
  • 内存开销(GC元数据开销

追踪垃圾回收

对象被回收的条件:指针指向关系不可达的对象

2.Go内存分配

分块

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

  • 调用系统调用mmap()向OS申请一大块内存,例如4MB
  • 先将内存划分成大块,例如8KB,称作mspan
  • 再将大块继续划分成特定大小的小块,用于对象分配
  • noscan mspan:分配不包括包含指针的对象——GC不需要扫描
  • scan mspan:分配包含指针的对象——GC需要扫描

对象分配:根据对象的大小,选择最合适的块返回

缓存

TCMalloc:thread caching
每个p包含一个mcache用于快速分配,用于为绑定于p上的g分配对象
mcache管理一组mspan
当mcache中的mspan分配完毕,向mcentral申请带有未分配块的mspan
当mspan中没有分配对象,mspan会被缓存在mcentral中,而不是立即释放并归还给OS