这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天,今天来对Go语言性能优化中的内存分配优化与编译器优化进行回顾,并学习了字节跳动公司对于这两点的的优化实践方案。
Go 内存管理分配及优化方式
分块分配方式
分块分配方式的核心思想为:在heap上分配内存前,提前将内存进行分块。
缓存分配方式
缓存分配方式的思路类似于计算机内存中的垂直结构。缓存中的每个块对应着一组更大的内存块,当访问丢失后,会将对应的内存块重新写入缓存中。
优化方式
对于带缓存的分块分配方式,由于对象分配的操作频繁同时内存分配的路径较长,会导致分配内存十分耗时。对于这一问题,字节内部开发了Balanced GC对对象分配进行优化,优化的思路为使用一个特定的结构GAB,用于维护小对象的内存分配,同时使用三个指针维护GAB内的地址,并通过指针碰撞的风格为对象的内存进行分配。
编译器优化
编译器结构
编译器的分析分为前端与后端,其中前端包括了词法分析、语法分析、语义分析和中间代码生成,后端则包括了代码优化和目标代码生成。
静态分析
静态分析通过分析程序的数据流和控制流,从而推导程序的行为和性质,缩短程序运行路径,优化程序的运行效率。
过程内分析和过程间分析
过程内分析仅在函数内部进行分析,而过程间分析需要考虑参数的传递和返回值,较为复杂。
编译器优化的思路
字节内部的优化方案名为Beast Mode,主要的策略有:用编译时间换取更高效的机器码;通过函数内联,将过程间分析转化为过程内分析、降低开销的同时,帮助其他分析策略有更多用武之地(如逃逸分析)。