这是我参与「第五届青训营 」伴学笔记创作活动的第 4 天
文章是根据青训营课程做的随堂笔记,需要参考课程资料食用。
一、自动内存管理
- 动态内存分配
和C语言一样,程序在运行时可以根据需求手动分配内存
malloc() - 自动内存管理--(垃圾回收): Go语言增加了逃逸分析和GC,底层实现的系统自动管理动态内存,可以避免程序员花精力去手动内存管理,引发内存泄漏等问题,帮助我们专注于业务逻辑的实现。 其包括三个要点:
- 为新对象分配空间
- 找到存活对象
- 回收死亡对象的内存空间
Mutator:业务线程,用于分配新的对象,修改引用关系
Collector:GC线程,用于找寻存活对象,回收死亡对象的内存空间
Serial GC:只有一个collector
Parallel GC:支持多个collectors同时回收的GC算法
Concurrent GC:mutator和colector可以同时执行,collectors必须感知对象指向关系的改变。
GC的实现主要分为三大类:
一是引用计数;
二是标记清除,
利用追踪垃圾回收的技术,标记用来找到可达对象,清理用来清除所有不可达对象。
三是复制。
分代GC
分代GC(Generative GC)建立在这样的假说上:大部分新分配的对象存货周期较短,在分配后的第一轮GC中就会被回收掉。基于这个假说,垃圾回收只需要去扫描和清扫新分配的对象就可以清扫掉大部分需要回收的对象,以此降低内存管理的开销。
引用计数
每个对象都有相应的引用数目,对象存活的条件是当且仅当引用数>0,也就是不至于被遗弃在内存中无人访问。这样,内存管理的操作可以被分配到程序执行过程中。
然而,现在的所有GC自动内存管理依旧存在不足之处,大家一直在寻求改进。
二、内存分配
分块
分块是为了对象在堆内存中分配内存,所以需要提前把内存分块。先将内存划分为大块,例如8KB,乘坐mspan,再将大块继续划分为特定大小的小块,用于对象分配。
缓存
每个p包含一个mcache用于快速分配的对象,mcache管理一组mspan,当mcache中的mspan分配完毕,向mcentral申请带有未分配块的mspan。当mspan中没有分配的对象,mspan会被缓存在mcentral中,而不是立即释放。
优化方案是Balanced GC。本质是将多个小对象的分配合并成一次大对象的分配。实现了copying GC,有很大的性能收益。
三、编译器和静态分析
这块就略了。