这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
优化
自动内存管理
动态内存 程序在运行时根据需求动态分配的内存:malloc()
垃圾回收 有程序语言的运行时系统回收动态内存
做到为新对象分配空间,找到存活对象,回收死亡对象的内存空间
Concurrent GC必须感知对象指向关系的改变
追踪垃圾回收
回收指针指向关系不可达的对象
标记根对象:静态变量、全局变量、常量、线程栈等
标记:找到可达对象
求指针指向关系的传递闭包:从根对象出发,找到所有可达对象
清理:所有不可达对象
Cpoying GC:将存活对象复制到另外的内存空间
Mark-sweep GC:将死亡对象的内存标记为“可分配”
Mark-compact GC:移动并整理存活对象
根据对象的生命周期,使用不同的标记和清理策略
分代GC Generational GC
很多对象在分配出来后很快就不再使用了,故给每个对象设置一个年龄,也就是经历过GC的次数,将年轻和老年的对象,制定不同的GC策略,降低整体内存管理的开销,不同年龄的对象处于heap的不同区域\
引用计数
每个对象都有一个与之关联的引用数目,当且仅当对象引用数大于0时对象存活\
自动内存管理和Go内存管理机制
Go内存分配-分块
提前将内存分块
调用系统调用mmap()向OS申请一大块内存,先将内存划分为大块,称作mspan,再将大块继续划分成特定大小的小块,用于对象分配
noscan mspan:分配不包含指针的对象——GC不需要扫描
scan mspan:分配包含指针的对象——GC需要扫描\
Balanced GC
每个g都绑定一大块内存,称作GAB,用于noscan类型的小对象分配,使用三个指针维护GAB,base,end,top,Bump pointer风格对象分配
本质是将多个小对象的分配合并成一次大对象的分配,但该分配方式会导致内存被延迟释放。针对该问题,采用移动GAB中存活的对象来解决。当GAB总大小超过一定阈值时,将GAB中存活的对象赋值到另外分配的GAB中,然后释放原先的GAB。用的是copying GC的算法处理小对象
编译器
结构
源代码->词法分析器->语法分析器->语义分析器->中间表示->代码优化->代码生成->目标代码