Go语言学习笔记 · 第十二节
《Go语言学习笔记》第十二节
垃圾回收以span为单位进行。清理函数sweepone触发mSpan_Sweep,遍历span,把不可达对象并入freelist;若span全部收回则归还heap。
垃圾回收以span为单位进行。清理函数sweepone触发mSpan_Sweep,遍历span,把不可达对象并入freelist;若span全部收回则归还heap。往heap放入span时会尝试合并相邻空闲span。回收出的span等待复用,监控任务sysmon定期检查heap中的空闲块,闲置超时则通过madvise等机制释放物理内存(虚拟地址空间保留),Windows则需用VirtualFree。也可调用FreeOSMemory主动释放。
运行时自身管理对象(如mspan、mcache)由专门的FixAlloc固定分配器管理,初始化heap时创建4种,分配时优先取复用链表,仅mspan关联recordspan以按需扩张h_allspans供GC遍历。
GoGC采用非分代、非紧缩、写屏障、并发标记清理。核心问题是抑制堆增长并平衡CPU:由控制器记录状态、动态调整策略与next_gc阈值;分配过快时用户线程参与辅助回收;GCgoroutine循环等待触发条件。标记分两步:gcscan_m扫描ROOT区域和goroutine栈,经scanblock比对bitmap找出指针,加入gcWork队列;多个MarkWorker由调度器唤醒,按三种模式处理灰色对象,遍历引用并转黑。STW阶段的gcMark负责收尾,禁用并发时回退到阻塞模式,由helpgc唤醒线程执行gchelper完成mark+drain。清理则由专门goroutine死循环遍历span触发回收。