这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
比较全面地了解了go语言垃圾回收机制,对内存管理系统有了较系统地认知
一.自动内存管理(GC)
动态内存:程序在运行时根据需求动态分配内存malloc()
自动内存管理(垃圾回收):系统动态回收
三个任务:
- 为对象分配空间
- 找到存活对象
- 回收死亡对象
相关术语:
- Mutator:业务线程,分配新对象
- Collector: Gc线程,回收死亡对象
- Serial GC:只有一个collector
- Parallel GC:多个Collector同时回收
- Concurrent GC:mutator(s)和collector(s)可以同时执行
如何评价GC算法:
- 安全性:不能回收存活对象
- 吞吐率:花在GC上的时间占比
- 暂停时间长短
- 内存开销:越小越好
如何选择GC:根据对象生命周期,使用不同标记和清理策略
存在以下策略:
- Mark-sweep GC:使用free list管理空闲内存
- copying GC:将对象复制导另外的内存空间
- Compact GC:原地整理对象
分代假说:
- 对象年龄:经历GC次数
对于年轻代:由于存活对象很少,可以采用copying collection
对于老年代:对象趋势一直活着,反复复制开销较大,采用mark-sweep collection
二.内存分配
思想:分块加缓存
- 分块:根据对象大小分配相应大小的块
- 缓存:没有需要分配内存的对象时,mspan会被缓存而不是立即归还
优化方案:Balanced GC
用于nascan类型小对象分配,先绑定一大块内存,
通过三个指针维护:base,size,top,通过移动指针分配内存
(大对象可能会被延迟释放内存)
三.编译器与静态分析
1.编译器结构
重要系统软件
- 识别程序是否非法
- 生成正确高效代码
分析部分(前端)
- 词法分析,生成词素
- 语法分析,生成语法树
- 语义分析,收集类型信息
- 中间代码生成
综合部份(后端)
- 代码优化,及其无关优化,生成优化后的IR
- 代码生成,生成目标代码
2.静态代码分析
不执行代码,推导执行行为
分析对象:
- 控制流:程序执行流程
- 数据流:数据在控制流上的传递
分析方式:
- 过程内分析:过程内部分析
- 过程间分析
3.编译器优化
方式:
函数内联:
- 将被调用的函数体副本替换到调用位置,重写代码以反映参数绑定
逃逸分析:
观察指针p在当前作用域:
- 作为参数传递给替他函数
- 传递给全局变量
- 传递给其他goroutine
- 传递给已逃逸的指针指向的对象
则为逃逸