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

62 阅读2分钟

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

Go语言的内存管理是通过垃圾回收来实现的。Go语言采用了一种称为"标记-清除"的垃圾回收算法,它会找出所有还在使用的对象,并将所有未使用的对象清除掉。这种方式在处理大量短暂对象时,会比其他垃圾回收算法效率更高。Go语言还支持手动内存管理,如通过"new"和"make"关键字来分配和释放内存。

day4 Go 语言内存管理

  1. 自动内存管理

  • Concurrently 是什么意思?
  • Mutator threads 指的是什么?

相关概念

追踪垃圾回收

  • Copying GC: 将对象复制到另外的内存空间
  • Mark-sweep GC: 使用free list 管理空闲内存
  • Compact GC: 原地整理对象

分代GC (Generational GC)

引用计数

总结

  • 自动内存管理的背景和意义

  • 概念和评价方法

  • 追踪垃圾回收

  • 引用计数

  • 分代GC

  • 学术界和工业界在一直在致力于解决自动内存管理技术的不足之处

    • PLDI'22 Low-Latency,High-Throughput Garbage Collection
  1. Go内存管理及优化

Go内存分配--分块

  • 目标:为对象在heap上分配内存

  • 提前将内存分块

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

Go内存分配一缓存

Go内存管理优化

我们的优化方案:Balanced GC

总结

  • go内存管理一分块

  • G0内存管理一缓存

  • G0对象分配的性能问题

    • 分配路径过长
    • 小对象居多
  • Balanced GC

    • 指针碰撞风格的对象分配

    • 实现了copying GC

    • 性能收益

  1. 编译器和静态分析

编译器的结构

静态分析

过程内分析和过程间分析

总结

  • 编译器的结构与编译的流程
  • 编译器后端优化
  • 数据流分析和控制流分析
  • 过程内分析和过程间分析
  1. Go编译器优化

函数内联

Beast Mode 与逃逸分析

总结

  • Go编译器优化的问题
  • Beast mode
  • 函数内联
  • 逃逸分析
  • 通过micro-benchmark快速验证性能优化
  • 性能收益