这是我参与「第五届青训营」笔记创作活动的第4天
一. 重点内容
-
自动内存管理
-
Go语言内存管理及优化
-
编译器和静态分析
-
Go语言编译器优化
二. 知识点介绍
1. 性能优化
- 性能优化:提升软件系统处理能力,减少不必要的消耗,充分发掘计算机算力
- 为什么要性能优化:提升用户体验;资源有效利用
- 性能优化的层面:如业务层优化(容易获得较大性能收益)、语言运行时的优化以及数据驱动层面的优化
2. 自动内存管理
- 动态内存:程序在运行时根据需求动态分配的内存:malloc()
- 自动内存管理(垃圾回收):由系统管理动态内存
-
- 避免手动内存管理,专注于实现业务逻辑
-
- 保证内存使用的正确性和安全性: double-free problem, use-after-free problem
- 相关概念:
-
- Mutator: 业务线程,分配新对象,修改对象指向关系
-
- Collector: GC线程,找到存活对象,回收死亡对象的内存空间
-
- Serial GC: 只有一个collector
-
- Parallel GC: 并行GC,支持多个collectors同时回收的GC算法
-
- Concurrent GC: 并发GC,支持mutator(s)和collector(s)可以同时执行的GC算法
- GC算法:
-
- Safety:不能回收存活的对象
-
- Throughput:1 - GC时间/程序执行总时间
-
- Pause time:stop the world(STW)
-
- Space overhead:GC元数据开销
- 追踪垃圾回收(Tracing garbage collection):根据对象的生命周期,使用不同的标记和清理策略
-
- 对象被回收的条件:指针指向关系不可达的对象
-
- 标记根对象 (GC roots): 静态变量、全局变量、常量、线程栈等
-
- 标记:找到所有可达对象
-
- 清理:回收所有不可达对象占据的内存空间
- 引用计数:
-
- 每个对象都有一个与之关联的引用数目
-
- 对象存活的条件:当且仅当引用数大于0
-
- 优点:指针传递的过程中进行引用计数的增减;不需要了解 runtime 的细节
-
- 缺点:开销大,因为对象可能会被多线程访问,需要用原子操作保证原子性和可见性;无法回收环形数据结构;每个对象都引入额外存储空间存储引用计数;回收大的数据结构可能引发程序的暂停
3. Go内存管理及优化
- 目标:为对象在heap上分配内存(提前将内存分块)
- 对象分配:根据对象的大小,选择最合适的块返回
- 内存缓存:Go 内存管理构成了多级缓存机制,从OS分配得的内存被内存管理回收后,也不会立刻归还给OS,而是在Go runtime内部先缓存起来,从而避免频繁向OS申请内存。
- 编译器和静态分析:
-
- 静态分析:不执行代码,推导程序的行为,分析程序的性质
-
- 控制流:程序的执行流程
-
- 数据流:数据在控制流上的传递