求剧情
Go语言学习笔记 · 第十三节

《Go语言学习笔记》第十三节

本节先讨论垃圾回收的隐性泄漏问题:服务重启时大量分配对象会把触发阈值next_gc推得很高,之后活跃对象远少于该阈值,导致GC长期不触发、白色对象滞留。

本节先讨论垃圾回收的隐性泄漏问题:服务重启时大量分配对象会把触发阈值next_gc推得很高,之后活跃对象远少于该阈值,导致GC长期不触发、白色对象滞留。示例验证了这一现象,最终由sysmon监控每2分钟检查一次,超过2分钟未触发就强制执行forcegc,恢复阈值;forcegc goroutine同样采用循环休眠等待唤醒的模式。

随后介绍GC辅助结构:parfor负责任务分组与调度,把n个任务平均分给nthr个线程,线程调用parfordo获取任务组执行;gcWork包装无锁栈workbuf,采用类似内存分配器cache的本地缓存策略,缓存耗尽才与全局交换,用完的workbuf放回work.empty复用;无锁栈用CAS实现,为避免ABA问题,采用指针加计数器的Double-CAS。此外还有mstats与MemStats统计结构,用户通过runtime.ReadMemStats获取,但该函数会STW,需控制调用频率。

最后一部分讲调度器模型:P控制并发任务数量并提供执行资源,G只保存任务状态与栈,M是实际执行体,与P绑定循环执行G,三者数量不一一对应。schedinit初始化调度器,procresize调整P数量。go语句经编译为newproc调用,采用类似cdecl的约定复制参数;newproc1创建或复用G对象(默认2KB栈,由allg引用,执行完放回复用链表),初始化后优先放入P本地队列。任务队列分三级:P.runnext、P.runq、全局sched.runq,后者加锁且有runqputslow。

‹ 上一章目录下一章 ›

全部 17 章