垃圾回收(GC)

内存管理策略,在业务进程运行的过程中,由垃圾收集器以类似守护协程的方式在后台运行,按照指定策略回收不再被使用的对象,释放内存空间进行回收

优势:

屏蔽内存回收的细节:屏蔽复杂的内存管理工作,更好聚焦于业务逻辑

以全局视野执行任务:全局管理临界资源的使用

劣势:

提高下限但降低了上限:失去控制主权,除运用有限的GC调优参数外,更多的自由度都被阉割,需要向系统看起,服从设定

增加额外成本:需要额外的状态信息用以存储全局的内存使用情况,有时需要中断整个程序用以支持垃圾回收工作

垃圾回收算法

标记清扫

可达对象:对象和对象之间通过指针记录依赖关系,通过指针依赖的路径实现标记,从根对象出发将所能达到的对象全部进行标记

不可达对象:清扫完一轮后,剩下没有被标记的对象,代表不在被使用方所关心,就可以对内存进行回收

标记:标记出当前还存活的对象

清扫:清扫到未被标记到的垃圾对象

类似于排除法的间接思路,不直接查找垃圾对象,而是标记存活对象,取补集推断出垃圾对象

会产生内部碎片,因为清扫后,空闲的内存块可能零星碎片化分布,对大对象需要分配内存,可能会因为无法化零为整导致分配失败

标记压缩

在标记清扫的基础上进行压缩,在清扫的同时,对还存活对象进行压缩整合,将已使用的内存块进行位置的转移,压缩在一起使得更加紧凑

半空间复制

以空间换时间

分配两片大小相等的空间fromspace和tospace

每轮只使用fromspace空间(正常分配内存),以GC作为分水岭划分轮次

GC时,将fromspace存活对象转移到tospace中,进行空间压缩整合

GC后交换fromspace和tospace,开启新轮次

引用计数

对象每被其他对象引用一次,计数器加1

每被删除引用一次,计数器减1

GC时,把计数器等于0的对象删除,不在被用户需要

无法解决循环引用或自引用问题

Golang垃圾回收

并发三色标记法+混合写屏障机制

三色标记法

属于标记清扫算法的一种实现

对象分为:黑白灰

从稳定的根对象出发

黑:对象自身存活,且指向对象都已标记完成

白:对象尚未被标记到,可能是垃圾对象

灰:对象自身存活,其指向对象还未标记完成

标记开始前,将根对象(全局对象,栈上局部变量等)置黑,将其所指向的对象置灰

标记规则是,从灰对象出发,将其所执行的对象都置灰,之后对当前灰对象置黑

标记结束后,白对象就是不可达的垃圾对象,进行清扫