优化Go程序|青训营

86 阅读2分钟

性能优化:提升软件系统处理能力,减少不必要的消耗,充分发挥计算机算力。用户体验: 带来用户体验的提升资源高效利用: 降低成本,提高效率——很小的优化乘以海量机器会是显著的性能提升和成本节约性能优化的层面:业务层优化:针对特定场景,具体问题,具体分析,容易获得较大性能收益。语言运行时优化:解决更通用的性能问题,考虑更多场景,Tradeoffs。数据驱动:自动化性能分析工具 – pprof;依靠数据而非猜测;首先优化最大瓶颈。性能优化与软件质量:软件质量至关重要在保证接口稳定的前提下改进具体实现测试用例: 瘦盖尽可能多的场景,方便回归文档: 做了什么,没做什么,能达到怎样的效果隔离: 通过选项控制是否开启优化可观测:必要的日志输出自动内存管理动态内存:程序在运行时根据需求动态分配的内存: malloc()自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存。避免手动内存管理,专注于实现业务逻辑保证内存使用的正确性和安全性: double-free problem, use-after-free problem 分块 目标:为对象在heap上分配内存。 提前将内存分块: 调用系统调用 mmap() 向 OS 申请 大块内存,例如 4 MB 先将内存划分成大块,例如 8 KB,称作 mspan 再将大块继续划分成特定大小的小块,用于对象分配 noscan mspan:分配不包含指针的对象-GC不需要扫描 scan mspan:分配包含指针的对象需要扫描 对象分配:根据对象的大小,选择最合适的块返回 \newline 缓存 TCMalloc: thread cac 优化方案: Balanced GC 每个g 都绑定一大块内存 (1 KB),称作 goroutine allocation buffer (GAB) GAB 用于 noscan 类型的小对象分配: < 128 B 使用三个指针维护 GAB: base,end,top Bump pointer (指针碰撞) 风格对象分配:无须和其他分配请求互斥,分配动作简单高效 GAB 对于 Go 内存管理来说是一个大对象 本质:将多个小对象的分配合并成一次大对象的分配 方案:移动 GAB 中存活的对象 当 GAB 总大小超过一定闻值时,将 GAB 中存活的对象复制到另外分配的 GAB 中 原先的 GAB 可以释放,避免内存泄漏 本质: 用 copying Gc 的算法管理小对象,根据对象的生命周期,使用不同的标记和清理策略。 性能收益:高峰期 CPU usage 降低 4.6%,核心接口时延下降 4.5%~7.7%