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

75 阅读2分钟

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

3.优化方案:Balanced GC

  • 每个g都绑定一大块内存(1KB),称作goroutine allocation buffer (GAB)

  • GAB用于noscan类型的小对象分配:<128B

  • 使用三个指针维护GAB:base, end, top

  • Bump pointer (指针碰撞) 风格对象分配

    • 无须和其他分配请求互斥
    • 分配动作简单高效
  • GAB对于Go内存管理来说是一个大对象

  • 本质:将多个小对象的分配合并成一次大对象的分配

  • 问题:GAB的对象分配方式会导致内存被延迟释放

  • 方案:移动GAB中的存活对象

    • 当GAB总大小超过一定阈值,将GAB中的存活对象复制到另外分配的GAB中
    • 原先的GAB可以释放,避免内存泄漏
    • 本质:用copying GC的算法管理小对象

屏幕截图_20230217_224156.png

四、编译器和静态分析

1.编译器结构

分析部分(前端front end)

  • 词法分析,lexeme
  • 语法分析,生成语法树
  • 语义分析,收集类型检查,进行语义检查
  • 中间代码生成,IR

综合部分(后端back end)

  • 代码优化,机器无关优化,生成优化后的IR
  • 代码生成,生成目标代码

屏幕截图_20230219_174022.png

2.静态分析

不执行程序代码,推导程序的行为,分析程序的性质。

控制流(Control flow):程序执行的流程

数据流(Data flow):数据在控制流上的传递

通过分析控制流和数据流,得到更多关于程序的性质,根据这些性质优化代码。

3.过程内分析和过程间分析

  • 过程内分析(Intra-procedural analysis):仅在函数内部进行的分析
  • 过程间分析(Inter-procedural analysis):考虑过程调用时参数传递和返回值的数据流和控制流

为什么过程间分析是个问题?

  • 需要通过数据流分析得知i的具体类型,才能知道i.foo()调用的是哪个foo()
  • 根据i的具体类型,产生新的控制流,A.foo(),分析继续
  • 过程间分析需要同时分析控制流和数据流——联合求解,比较复杂

屏幕截图_20230219_174851.png