这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
自动内存管理
又称GC,保证内存使用的正确性与安全性
任务:
为新对象分配内存, 找到存活对象, 回收死亡对象的内存空间
GC的一些概念:
Mutator:业务线程,分配新对象,修改对象指向关系
Collector:GC线程,找到存活对象,回收死亡对象的内存空间,必须感知对象指向关系的改变,防止父对象被回收而子对象没有被回收
Serial GC:只有一个collector执行
Parrallel GC:支持多个collector同时回收GC
Concurrent GC:mutator(s) 和collector(s)可以同时执行
追踪GC:
1.标记根对象(堆,栈,全局变量区)
2.找到可达对象(保留下来的变量,将1, 2标记为存活对象,没被标记的为回收对象)
3.清理不可达对象,有以下方法,根据对象周期来选择不同策略:
copying gc:将回收对象剪切到另外的内存空间
mark-sweep gc:将回收对象内存标记为可分配
compact gc:原地整理内存空间
GC策略:
1.分代GC,每经过一次GC且存活后,年龄 + 1,为年轻代与老年代分区。
对年轻代使用copying gc,老年代使用mark-sweep gc,以增加吞吐量
2.引用计数,每被引用,引用数 + 1,优先回收引用数为0的对象
实例是c++11的智能指针
优点是内存操作平摊到了程序执行种,缺点是开销大,无法回收环形结构,依然可能引发暂停
缺点是可以解决的,并非固有的缺点。
Go内存管理及优化
Go内存分配:
提前向OS申请一大块内存,在其划分为大块,再继续划分为特定大小的小块,用于对象分配
Go缓存TCMalloc(thread caching):
用于快速为对象分配内存空间
堆内存管理优化:
为海量小型对象(<128B)分配内存地址,是十分耗时的工作
Balanced GC: 放弃g - m - p路径的内存分配方式,而是为g绑定一大块内存(1KB),使用三个指针维护,base,end,top,只需移动top指针来维护内存。(针对小对象noscan的优化策略)
noscan:不包含指针的对象
bitmap:便于快速寻址
回收小对象使用copying gc,以防止一个小对象阻碍一个gab的回收。