垃圾回收【Golang】
来自智得网
简介
垃圾回收是 Garbage Collection 的意思,通常简称为GC,是一种自动内存管理的机制。
当程序向操作系统申请的内存不再被需要时,因为不确定内存不再需要的时机,所以内存手动释放的开发量较大,而且极易出错,垃圾回收主动将不需要的内容空间回收并供其他代码进行内存申请时候复用,或者将其归还给操作系统,这种针对内存级别资源的自动回收过程,即为垃圾回收。负责垃圾回收的程序组件,即为垃圾回收器。
垃圾回收在现代语言中的使用非常广泛,例如Python,Java等语言都有垃圾回收器。
原理
垃圾回收算法需要关注几个部分:
- 从堆内存标记把垃圾也就是没有再被引用的内存标记出来
- 对内存标记出来的垃圾进行清理,从而释放内存
- 垃圾回收的策略,包括执行的时机,清理的比例等。
标记算法
并行标记的一般采用三色标记的方式进行标记,三色标记是指在标记过程中将对象分为白色,黑色,灰色三种。
颜色 | 定义 |
---|---|
黑色 | 对象自身扫描完成,并且完成了该对象所有引用的标记动作。 |
灰色 | 对象自身扫描完成,对象所引用的对象至少还有一个未标记完成,当标记完成之后变成黑色。
灰色是中间状态,当垃圾回收结束的时候只有白黑两种颜色。 |
白色 | 没有被垃圾回收扫描过,当扫描结束的时候白色对象可以被回收。 |
三色标记的过程如下:
- 初始阶段所有的对象都是白色。
- 初始标记完成之后将GC Roots直接关联的对象置为灰色。
- 遍历灰色对象的所有引用,当所有引用被标记完成之后,灰色对象置为黑色,该对象引用的对象置为黑色,重复该过程,直到所有的对象都变成黑色。
- 当标记过程结束,白色对象可以被回收。
三色标记算法有三类问题,多标问题,漏标问题,以及新对象的问题。
多标问题是指在垃圾回收过程中该对象是扫描到被引用的,但是过程中断开了所有的引用,此时该对象已经是事实的垃圾,但是被标记为黑色,也就是多标问题。
多标问题关联的对象一般称为浮动垃圾,其不影响垃圾回收的正确性,可以在下次垃圾回收的时候进行清理。
漏标问题是指在垃圾回收过程中,该对象被灰色对象引用,但是过程中灰色对象到该对象的引用断开,而同时又有黑色对象引用了该对象,黑色对象因为不会再进行引用对象的标记,该对象就不能被正确扫描,从而被漏标。
漏标问题一般有两种方式解决,原始快照和增量更新。
原始快照是断开灰色对象和其他对象链接的时候,会把该关联关系保存下来,扫描结束之后,使用这条关系的快照重新将该对象进行标记。
增量更新是指当黑色节点指向其他对象的时候,将这个新增的引用关系保存下来,扫描结束的时候,再重新扫描该黑色对象节点。