这是我参与「第五届青训营 」伴学笔记创作活动的第5天。
一、本堂课重点内容
主要了解了高性能go语言发行版优化和落地时间,分为内存管理优化和编译器优化,学习了自动内存管理和go语言内存管理机制,以及编译器优化的基本问题和思路。
二、详细知识点介绍
性能优化
是指提升软件系统处理能力,减少不必要的消耗,充分发掘计算机算力。为什么要做性能优化呢?其主要目的是为了提高用户体验以及资源高效利用。
性能优化的层面
业务层优化:针对特定场景,具体问题,具体分析。容易获得较大性能提升。
语言运行时优化:解决更通用的性能问题,考虑更多场景。
自动内存管理
动态内存:程序在运行时根据需求动态分配的内存,如c语言的malloc()函数。
自动内存管理(垃圾回收):由程序语言的运行时系统回收动态内存,避免手动内存管理,专注于实现业务逻辑,并且可以保证内存使用的正确性和安全性。
评价gc算法:
安全性:不能回收存活的对象;
吞吐率:花在gc上的时间;
暂停时间:stop the world业务是否感知;
内存开销:gc元数据开销;
追踪垃圾回收:
对象被回收的条件:指针指向关系不可达的对象。
1.标记根对象:静态变量,全局变量,常量,线程栈等。
2.标记:找到可达对象,求指针指向关系的传递闭包,从根对象出发。
3.清理:所有不可达对象,根据对象的生命周期,使用不同的标记和处理策略。
引用计数:
每个对象都有一个与之关联的引用书目。
对象的存活条件:当且仅当引用数大于0。
go内存分配
分块:
目标:为对象在heap上分配内存。
提前将内存分块,然后根据对象的大小,选择最适合的快返回。
缓存:
mcache用于快速分配,用于绑定分配对象。mspan中没有分配的对象,会缓存在吗central中,而不是立刻释放归还给OS。
go编译器优化
为什么要做编译器优化:
1.用户无感知,重新编译即可获得性能收益。
2.通用性优化。
编译优化的思路:
场景:面向后端长期执行任务。
用编译时间换取更高效的机器码。
函数内联:
将被调用函数的函数体的副本替换到调用位置上,同时重写代码以反映参数的绑定。
优点:此方法消除了调用函数的开销,将过程间分析转化为过程内分析。
逃逸分析:
分析代码中指针的动态作用域:指针在何处可以被访问。
大致思路:从对象分配出出发,沿着控制流,观察对象的数据流。若发现指针p在当前作用域s,作为参数传递给其他函数,或是传递给全局变量,或是传递给已逃逸的指针指向的对象,则指针p指向的对象逃逸出s,反之,则没有逃逸出s。
三、课后个人总结
经过本堂课的学习,我从自动内存管理、go内存管理、编译器和静态分析、编译器优化等方面学习了如何进行软件的性能优化,主要了解了高性能go语言发行版优化和落地时间,以及编译器优化的基本问题和思路。