Go 语言内存管理详解 | 青训营笔记

48 阅读2分钟

这是我参与「第五届青训营 」笔记创作活动的第2天

本次笔记根据课程第二节,主要分为三个模块:

Go 内存管理及优化

编译器和静态分析

Go 编译器优化

Go内存分配

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

提前将内存分块

缓存

每个p包含一个mcache用于快速分配,用于为绑定于p上的g分配对象 mcache管理一组mspan 当mcache 中的mspan分配完毕,向mcentral申请带有未分配块的mspan 当mspan中没有分配的对象,mspan会被缓存在mcentral 中,而不是立刻释放并归还给OS

image.png

Balanced GC优化方案

image.png 每个g都绑定一大块内存(1 KB),称作goroutine allocation buffer (GAB)

GAB用于noscan类型的小对象分配: <128 B

使用三个指针维护GAB: base, end, top

Bump pointer(指针碰撞)风格对象分配

image.png 本质:将多个小对象的分配合并成一次大对象的分配

编译器和静态分析

编译器结构

重要的系统软件 ·识别符合语法和非法的程序。生成正确且高效的代码分析部分

前端(front end)

词法分析,生成词素(lexeme)

语法分析,生成语法树 ​ 语义分析,收集类型信息,进行语义检查 ​ 中间代码生成,生成intermediate representation (IR)

综合部分(后端back end) ·代码优化,机器无关优化,生成优化后的IR·代码生成,生成目标代码

静态分析

不运行代码,分析代码程序的行为,分析其性质,优化代码

过程内分析和过程间分析

过程内分析(lntra-procedural analysis):仅在函数内部进行分析 过程间分析(Inter-procedural analysis):考虑函数调用时参数传递和返回值的数据流和控制流

Go编译器优化

函数内联

内联:将被调用函数的函数体(callee)的副本替换到调用位置(caller)上,同时重写代码以反映参数的绑定

逃逸分析

分析代码中指针的动态作用域,若指针p在当前作用域S传递出去,则逃逸成功