Go内存管理 目标:为对象在heap上分配内存
提前将内存分块
调用系统调用mmap( ),向OS申请一大块内存
先将内存划分成大块 mspan
再将大块继续划分成特定大小的小块,用于对象分配
noscan mspan :分配不包含指针的对象,GC不要扫描
scan mspan 分配包含指针的对象--GC需要扫描
对象分配:根据对象的大小,选择最合适的块返回
Go内存分配 - 缓存 TCMalloc:thread caching
每个p包含一个mcache用于快速分配,用于为绑定于p上的g分配对象
mache管理一组mspan
当mcache中的mspan分配完毕,向mcentral申请待有未分配块的mspan
当mspan中没有分配的对象,mspan会被缓存在mcentral中,而不是立刻释放并规划给OS
Go内存分配 - 分块 目标 为对象在heap上分配内存
提前将内存分块
调用系统调用mmap()向OS申请一大块内存
先将内存划分成大块
再将大块继续划分成特定大小的小块,用于对象分配
noscan mspan分配不包含指针的对象--GCbuxuyao1saomiao1
scan mspan分配包含指针的对象--GC需要扫描
对象分配:根绝对象的大小,选择最合适的块返回
Go内存管理优化 对象分配是非常高频的操作:每秒分配GB级别的内存
小对象占比高
Go内存分配耗时
分配路径长:g->m->p>mache->memory block->return poniter
pprof 对象分配的函数是最频繁调用的函数之一
优化方案 Balanced GC 每个g都绑定一大块内存
GAB用于noscan类型的小对象分配
使用三个指针维护GAB:base,end,stop
Bump poinyer(指针碰撞) 风格对象分配
无需和其他分配请求互斥
分配动作简单高效
Balanced GC GAB对于Go内存管理来说是一个大对象
本质:将多个小对象的分配合并成一次大对象的分配
问题:GAB的对象分配方式会导致内存被延迟释放
方案:移动GAB中存活的对象
当GAB总大小超过一定阈值时,将GAB中存活的对象复制到另外分配的GAB中
原先的GAB可以释放,避免内存泄露
本质:用copying GC 的算法管理小对象
根据对象的声明周期,使用不同的标记和清理策略
编译器和静态分析 编译器的结构 作用 重要的系统软件
识别符合语法和非法的程序‘
生成正确且高效的代码
分析部分 (前端 front end)
词法分析 生成词素
词法分析 生成语法树
语义分析,收集类型信息,进行语义检查
中间代码生成,声成intermediate representation(IR)
综合部分(后端 back end)
代码生成,机器无关优化,生成优化的IR
代码生成,生成目标代码