自动内存管理|青训营笔记

39 阅读4分钟

前言

这是我参与【第五届青训营】伴学笔记创作活动第四天,今天的学习内容主要为自动内存管理方面的内容,我认为自动内存管理可以更好的提升产品性能,可以更容易获得较大的性能收益。

正文

性能优化层面

  1. 业务代码
  2. SDK
  3. 基础库
  4. 语言运行时
  5. OS

业务层面优化:针对特定场景,具体问题具体分析;容易获得较大的性能收益

语言运行时优化:解决文艺更通用的的性能问题;考虑更多场景,Tradeoffs

数据驱动:自动化性能分析工具pprdf;依靠数据而非猜测;首先优化最大瓶颈

自动内存管理

  1. 动态内存:程序运行时根据需求动态分配内存:malloc()
  2. 自动内存管理(垃圾回收):有程序语言运行时回收系统动态内存;避免手动内存管理,专注于业务实现业务逻辑;摆正使用正确性和安全性:double-free problem,use-after-free problem
  3. 三个任务:为新对象分配空间;找到存活对象;回收死亡对象的内存空间
  4. 评价GC算法:安全性:不能回收存活的对象(基本要求);吞吐率;暂停时间:STW(业务是否感知,越短越好);内存开销:GC元数据开销(越小越好)
  5. 追踪垃圾回收:对象回收的条件:指针指向关系不可达的对象;
    标记根对象:静态变量,全局变量,常量,线程栈等;
    标记:找到可达对象:求指针指向关系的传递闭包:从跟对象出发,找到所有可达的对象; 清理:所有不可达对象(根据对象的生存周期,使用不同标记和清理策略)
  6. 分代GC:分类假说:most object die young;Intuition:很多对象在分配出来很快就不再使用;每个对象都有年龄:经过GC次数;目的:针对老年和年轻对象,指定不同的GC策略;不同年龄的的对象处于heap不同的区域;
  7. 年轻代:常规的对象分配;由于存活对象很少,可以采用copying collection;GC吞吐率很高
  8. 老年代:对象一致趋向于活着,反复复制开销较大;可以采用mark-sweep collection
  9. 引用计数:给每个对象都有一个引用数目,对象存活条件,当且仅当引用数大于0;(优点:内存管理的操作被平摊到程序执行过程中,内存不需要了解runtime的实现细节)(缺点:维护开销较大,无法回收环形数据结构,内存开销,回收时可能引入暂停)

GO内存分配

  1. 目标:为对象在heap上分配内存,
  2. 分块:提前将内存分块;对象分配:根据对象大小,选择最适合的块返回;
  3. 缓存:
  4. 优化:小对象占比较高;Go内存分配比较耗时
  5. Balanced GC:本质:将多个小对象的分配合并成一次大对象的分配

编译器和静态分析

  • 1.静态分析:不执行代码,推到程序的行为,分析程序的性质
    1. 控制流静态分析:程序执行的流程
  • 3.数据流静态分析:数据在控制流上的传递
  • 4.过程内分析:仅在过程内部进行分析
  • 5.过程间分析:考虑过程调用时渗透参数传递和返回值的数据流和控制流(同时分析数据流和控制流,比较复杂)

GO编译器优化

  1. 函数内联:优点:消除函数调用的开销,将过程间分析转化为过程内分析,帮助其他优化;缺点:函数体变大,不友好,编译生成的GO镜像变大
  2. Beast Mode:调整内联策略,使更多函数内联
  3. 逃逸分析:分析代码中指针的的东涛作用域,:指针在何处可以被访问
  4. 思路:从对象分配处出发,沿着控制流;观察对象的数据流,若发现指针p在当前作用域s(作为参数传递给其他参数;传递给全局变量;传递给其他goroutine;传递给以逃逸的指针指向对象);则指针p指向的对象逃逸出s,反之则没有逃逸出s
  5. beast mode:函数内联扩展了函数边界,更多对象不逃逸(优化:没逃逸对象可以在栈上分配;对象在栈上分配回收很快,移动sp,减少在heap上的分配,降低GC负担)

个人总结

以上是我今日的笔记,通过本节课我对go语言了解更深刻,对于编译器我以前只知道它是编程必不可少的工具,这节课过后我对编译器了解更加深刻,对于静态分析,我认为这是编辑器很重要的一个过程,同时对分析问题和解决问题的有了更好的思路,对我以后的学习过程有很大的帮助。