Go语言的优化(内存优化和编译器优化)|青训营笔记

229 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第4篇笔记

老师讲的很清楚,就是这块儿内容比较深,这里讲的太浅了,之后进行补充吧

两个方面:

  1. 内存管理优化
  2. 编译器优化

性能优化方面:

  1. 业务层优化
  2. 语言运行时优化
  3. 数据驱动
  • 自动化性能分析工具--pprof
  • 依靠数据而非猜测
  • 首先优化最大瓶颈

要注意一下编辑sdk,里面的兼容性

总结

  • 性能优化的基本问题
  • 性能优化的两个层面
  • 性能优化的可维护性

课程目录:

  1. 自动内存管理

自动内存管理的基本概念

  1. Go内存管理及优化

Go内存管理的性能问题以及优化思路

  1. 编译器和静态分析

编译原理和机器无关的优化

  1. Go编译器优化

Go编译器优化思路

自动内存管理分配

1.1 自动内存管理

  • 动态内存

程序在运行时根据需求动态分配的内存:malloc()

  • 自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存

避免手动内存管理,专注于实现业务逻辑

保存内存使用的正确性和安全性:doublefree problem,use-after-free problem

  • 三个任务
    • 为新对象分配空间
    • 找到存活对象
    • 回收死亡对象的内存空间

相关概念:

  • mutator: 业务线程,分配新对象,修改对象指向关系
  • collector: GC线程,找到存活对象,回收死亡对象的内存空间
  • serial GC: 只有一个collector
  • parallel GC: 支持对个collectors同时回收GC算法
  • Concurrent GC: mutators和collectors可以同时执行

serial、parallel都需要暂停

concurrentGC: 必须感知到对象指向关系的改变

如何评价GC

追踪垃圾回收

  • 对象被回收的条件:指针指向关系不可达的对象
  • 标记跟对象:
    • 静态变量、全局变量、常量、线程栈等
  • 标记:找到科大对象
    • 求指针指向关系的传递闭包:从跟对象触发,找到所有可达对象
  • 清理:所有不可达对象
    • 将存活对象复制到另外的内存空间 coping gc
    • 将死亡对象的内存标为“可分配” mark-sweep gc
    • 移动并整理存活对象 mark-compact gc
  • 根据对象的生命周期,使用不同的标记和清理策略

coping GC

mark-sweep gc:

compact gc:原地整理对象

coping gc 和compact gc很像

只是copying gc是另外的空间,而 compact gc 是原地做

如何应用GC?

根据不同的生命周期

引用计数

总结:

  • 自动内存管理的背景和意义
  • 概念和评价方法
  • 追踪垃圾回收
  • 引用计数
  • 分代gc
  • 学术界和工业界一直致力于解决不足

Go的内存管理以及优化

2.1 go 内存分配

  • 目标:为对象在heap上分配内存

( 疑问:

go 和C++不一样吧?

我看到说 go 的内存 分配不区分 堆、栈;有时候是堆、有时候是栈

和C++那种栈:临时变量 堆:动态分配的

)

  • 提前将内存分块

go 内存管理优化

总结:

  • Go内存管理----分块
  • Go内存管理----缓存
  • Go对象分配的性能问题
    • 分配路径过长
    • 小对象居多
  • valanced gc
    • 指针碰撞风格的对象分配
    • 实现了copying gc
    • 性能收益

编译器

总结:

  • 编译器的结构与编译 的流程
  • 编译器后端优化
  • 静态分析
    • 数据流分析和控制流分析
    • 过程内分析和过程间分析

Go编译器优化

  • 函数内联
  • 逃逸分析