GO内存管理| 青训营笔记

105 阅读3分钟

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

内存管理

自动内存管理

概念与背景

自动内存管理管理的是动态内存,是程序运行时根据需求分配的内存。而自动管理内存(垃圾回收)是程序语言的运行时系统管理内存,避免手动内存管理,专注于业务逻辑,降低开发成本,保证内存安全性和正确性。GC需要为对象分配空间,找到存活对象并回收死亡对象。

  • Mutator:业务线程,分配新对象,修改对象指向关系
  • collector:GC线程,找到存活对象,回收死亡对象内存空间
  • Serial GC:只有一个GC
  • Parallel GC:多个GC
  • Concurrent GC:多个GC并且Mutator可以和Collector可以同时执行 image.png

Tracing GC

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

  1. 标记根对象:静态变量、常量等指针指向对象标记为存活
  2. 找到并标记可达对象:根据指针求指针指向关系闭包,找到所有可达对象
  3. 清理所有不可达对象:清理策略包括COPY GC(将存活对象复制到其他空间),Mark-Sweep(将死亡对象地址标记为可分配),Mark-compact GC(转移并整理存活对象)

Generational GC

分代假说:许多对象分配后很快就不被使用了
基于该假说,为对象设置“年龄”属性,每经过一次GC不被回收,年龄+1。对不同年龄对象置定不同GC策略,降低整体内存管理开销。

  • 对于Young generation 常规的内存分配,由于存活的对象很少,可以采用Copy collect策略。
  • 对于Old generation 老年代对象区趋于长期存在,反复复制开销很大,可以采用mark-sweap collection策略
    image.png

Reference Counting

原理:每个对象都有与之关联的引用数目,对象存活条件是引用数大于0。

  1. 优点:
  • 内存管理的操作平摊到执行过程中
  • 内存管理不需要了解runtime实现细节
  1. 缺点
  • 维护引用计数开销较大:原子操作
  • 会有引用循环
  • 每个对象需要增加内存空间存储引用数目
  • 回收内存时可能引发

GO内存管理以及优化

对象分配

  • go中对象分配是一个高频操作:每秒分配GB级别
  • 小对象占比高
  • GO内存分配耗时
    基于以上特性,提出优化方案:Balanced GC
  1. 每个GOROUTINE绑定一块1KB内存,称为GAB,用于小对象分配
  2. 三个指针维护GAB:base,end,top(分别是基地址、尾地址、当前地址)
  3. Bump pointer风格对象分配
    image.png 一个缺点是会导致内存延迟释放,解决方法是移动GAB中存活的对象。

小结

以上讲述了GO内存管理中自动内存管理和优化。主要是介绍底层原理。关于复杂的实现需要自己多熟悉。