这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
1. 性能优化是什么?
- 提升软件系统处理能力,减少不必要的消耗,充分发掘计算的计算力。
2. 为什么要做性能优化?
- 用户体验:带来用户体验的提升--让刷抖音更加丝滑,让双十一购物不再卡顿。
- 资源高效利用:降低成本,提高效率--很小的优化乘以海量机器会是显著的性能提升和成本节约。
3. 性能优化的层面
业务代码、SDK、基础库、语言运行时、OS
- 业务层优化
-
- 针对特定场景,具体问题,具体分析
-
- 容易获得较大性能收益
- 语言运行时优化
-
- 解决更通用的性能问题
-
- 考虑更多场景
-
- Tradeoffs
- 数据驱动
-
- 自动化性能分析工具--pprof
-
- 依靠数据而非猜测
-
- 首先优化最大瓶颈
4. 自动内存管理
- 动态内存
-
- 程序在运行时根据需求动态分配的内存:malloc()
- 自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存
-
- 避免手动内存管理,专注于实现业务逻辑
-
- 保证内存使用的正确性和安全性:double-free problem,use-after-free problem
- 三个任务
-
- 为新对象分配空间
-
- 找到存活对象
-
- 回收死亡对象的内存空间
5. Go语言内存分配
- 分块
- 缓存
6. Go语言内存管理优化
- 对象分配是非常高频的操作:每秒分配GB级别的内存
- 小对象占比较高
- Go内存分配比较耗时
-
- 分配路径长:g -> m -> p -> mcache -> mspan -> memory block -> return pointer
-
- pprof:对象分配的函数是最频繁调用的函数之一
7. 编译器的结构
- 重要的系统软件
-
- 识别符合语法和非法的程序
-
- 生成正确且高效的代码
- 分析部分(前端front end)
-
- 词法分析,生成词素(lexeme)
-
- 语法分析,生产语法树
-
- 语义分析,收集类型信息,进行语义检查
-
- 中间代码生成,生成 intermediate representation(IR)
- 综合部分(后端back end)
-
- 代码优化,机器无关优化,生成优化后的IR
-
- 代码生成,生成目标代码
8. Go编译器优化
- 为什么做编译器优化
-
- 用户无感知,重新编译即可获得性能收益
-
- 通用性优化
- 现状
-
- 采用的优化少
-
- 编译时间较短,没有进行较复杂的代码分析和优化
- 编译优化的思路
-
- 场景:面向后端长期执行任务
-
- Tradeoff:用编译时间换取更高效的机器码
- Beast mode
-
- 函数内联
-
- 逃逸分析
-
- 默认栈大小调整
-
- 边界检查消除
-
- 循环展开
-
- ......
9. 总结
通过本节课程的学习,对于Go语言的内存管理、性能优化方面的知识点有了一定的认识。尤其是对于内存分配的分块和缓存方面的内容有着比较深刻的理解,设计的方面也是非常的高效。使得内存的利用效果大大提升。合理的分配了内存,尽量减少了不必要的内存消耗。