Go语言设计与实现之垃圾回收
文章目录
go的GC
GC主要作用于堆区。
相比于C、C++等语言手动管理内存机制,go具备GC机制。GC的意思是垃圾回收,用以回收不再使用的内存空间。GC期间可能发生STW问题,go一直在迭代优化GC,以降低GC导致STW的时间。
设计原理
标记清除法
- 标记阶段:从根对象出发查找并标记堆中所有的存活的对象
- 清除阶段:回收未被标记的对象的内存空间,并追加到空闲链表里
标记清除法需要暂定程序运行(较长的STW),执行标记清除之后,才恢复程序执行。
三色标记法
三色标记法是对标记清除法的改进,进一步减少了STW的时间。
-
白色对象
潜在的垃圾,其内存可能会被垃圾收集器回收
-
黑色对象
活跃的对象,包括不存在任何引用外部指针的对象以及从根对象可达的对象
-
灰色对象
活跃的对象,因为存在指向白色对象的外部指针,垃圾收集器会扫描这些对象的子对象
工作过程:
- 从灰色对象的集合中选择一个灰色对象并将其标记成黑色;
- 将黑色对象指向的所有对象都标记成灰色,保证该对象和被该对象引用的对象都不会被回收;
- 重复上述两个步骤直到对象图中不存在灰色对象;
因为需要暂停整个程序以完成三色标记+清除,三色标记法依然需要较长的STW。
所以,为了减少垃圾回收带来的STW时间过长问题,我们需要可以采取增量或并发GC的方式,加快GC。
混合写屏障
要实现正确的增量或并发GC,需要保证三色不变性,而三色不变性是通过屏障技术实现的(go中实现的是混合写屏障)
增量和并发收集
-
增量收集
增量地标记和清除垃圾,虽然会增加单次GC周期,但是会减少单次程序暂停的最长时间
-
并发收集
利用多核CPU的优势,加快垃圾收集
触发时机
runtime.sysmon
和runtime.forcegchelper
— 后台运行定时检查和垃圾收集(每2分钟);runtime.GC
— 用户程序手动触发垃圾收集;runtime.mallocgc
— 只要申请内存时,堆大小达到控制器计算的触发堆的大小就会触发垃圾收集;
文章作者 cold-bin
上次更新 2023-10-29