自动内存管理 | 青训营笔记

93 阅读3分钟

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

自动内存管理

概念介绍

基础知识

  • 业务线程(Mutator):分配新对象,修改对象指向关系
  • Collector:GC 线程,找到存活对象,回收死亡对象
  • 序列(Serial):Serial GC,只有一个 collector。收集时需要业务线程暂停。
  • 并发(Concurrent):管理多任务的方式,仍然在一个处理器上运行。Concurrent GC,mutator 和 collector 同时进行
  • 并行(Parallel):多个处理器同时运行多个任务。Parallel GC,支持多个 collector 同时回收。

垃圾回收

  • 追踪垃圾回收(Tracing garbage collection):标记可达对象,清除不可达对象。清理方法如下:

    • semi-space collector(coping):将内存空间均分为两部分,其中一部分达到容量上限时,触发垃圾回收,将可达对象复制到另一半空间

gc_copy_opengenus

  • mark and sweep:递归遍历可达对象(mark),遍历所有对象并清除不可达(sweep)

)

  • mark and compact:相当于复制算法的改进版,降低了空间开销

gc_compact

  • 引用计数:

    • 给对象添加引用计数器,为 0 时即可清除。
    • 优点:内存管理的操作被平摊到程序执行过程中。
    • 缺点:开销大;环形结构无法回收;无法避免暂停
  • 分代回收:

    • 原理:大多数对象会夭折。
    • 当新生代内存满时,可以使用复制算法清除。老年代满时,使用 mark-sweep 法清除。

Go 内存管理和优化

image-20230119114126132

image-20230119114313458

TCMalloc(Thread-Caching Malloc)

定长记录,不定长记录

  • free list:用链表存储未分配内存,表头用于分配,表尾用于收集回收的内存。常用于定长记录
  • 内存分块:将内存分块,给对象分配整数倍的块

mmap()(memory-mapped)

内存映射实现了虚拟内存,可以操作比内存更大的文件。或者实现从内核缓冲区到用户缓冲区的映射,减少上下文切换

 func Map(f *os.File, prot, flags int) (MMap, error) 

prot:映射的保护等级(读写权限)

flagsunix.MAP_SHAREDunix.MAP_PRIVATEunix.MAP_ANON

课上-性能优化及自动内存管理

优化角度

  • 业务层优化

  • 语言运行时优化

  • 数据驱动

    • 使用性能分析工具-pprof
    • 优先优化最大瓶颈

工作原则

  • 测试用例覆盖面尽可能广
  • 文档:已实现,未实现,效果
  • 隔离:通过选项控制是否开启
  • 可观测:输出日志

自动内存管理

优势

  • 降低开发难度
  • 保证内存使用安全性和正确性

评价指标

  • 安全性:不回收存活对象
  • 吞吐率:1-\frac{GC时间}{程序执行总时间},即花在GC上的时间
  • 暂停时间
  • 内存开销

编译器优化

函数内联

将 callee 的副本替换到 caller 位置上,同时重写代码反映参数的绑定

  • 优点:消除调用开销;转化为过程内分析,方便其他优化
  • 缺点:函数体变大,icache 不友好

Beast Mode

调整内联策略,内联更多函数