垃圾回收:指内存中不再使用的内存区域,自动发现和释放这种内存区域的过程就是垃圾回收。
三色标记原理
初始所有对象白色。
从根(root)出发(全局指针和goroutine栈上的指针)扫描所有可达对象,标记为灰色,放入待处理队列。
从队列取出灰色对象,将其引用对象标记为灰色放入队列,自身标记为黑色。
重复 3,直到灰色对象队列为空。此时白色对象即为垃圾,进行回收。
原理
WB(write barrier:写屏障,go1.7Dijkstra写屏障,只监控堆上指针数据的变动(增量式垃圾回收时,新增的指针对象会被初始为白色,需要标记为黑色)re-scan。go1.8混合写屏障,只监控堆上指针数据的变动,无需re-scan)-STW(stop the world:暂停所有正在执行的用户线程/协程)-mark(三色标记,标记协程是并行的)-WB(关闭写屏障)-STW(挂起stw协程)-sweep(清除,唤醒清扫垃圾协程,该协程在应用启动后创建,创建后立即进入睡眠,被唤醒后把白色对象挨个清理掉,清扫协程和应用协程是并发进行的,清扫完成后再次进入睡眠状态)
回收方式
非增量式:垃圾回收需要STW,在STW期间完成所有垃圾对象的标记,STW结束后慢慢的执行垃圾对象的处理。
增量式:垃圾回收需要STW,在STW期间完成部分垃圾对象的标记,然后结束STW继续执行用户线程,一段时间后再次执行STW再标记部分垃圾对象,这个过程会多次重复执行,直到所有垃圾对象标记完成。
GC触发条件
辅助GC:在分配内存时,会判断当前的Heap内存分配量是否达到了触发一轮GC的阈值(每轮GC完成后,该阈值会被动态设置),如果超过阈值,则启动一轮GC。
调用runtime.GC()强制启动一轮GC。
sysmon是运行时的守护进程,当超过 forcegcperiod (2分钟)没有运行GC会启动一轮GC。