(昨天参加面试被问到垃圾回收机制,一时想不起来,在此记录一下)
-
引用计数法
对象如果引用1次引用数加一,取消引用一次引用数-1,如果引用数为0就触发垃圾回收机制
-
标记清除法
首先我们将所有的对象标记为0,将存活的对象标记为1将标记为0的对象清除掉,然后将标记为1的对象重新标记为0,方便下一次垃圾回收,但是有一个问题就是:不连续,找位置是个问题
找位置:
First-fit:找到能放置下新对象的第一个块位置
Best-fit:找到能防止下新对象的最小的块
Worst-fit:找到最大的块,切一块空间个新对象
注意:
V8对垃圾回收机制的优化
优化标记算法,有些对象需要频繁回收而有些对象不需要频繁回收,所以在堆内存中分出两个空间一个是新生代区域(小、新、存活短),一个是老生代区域(大、老、存活长)。
新生代区域又分出两个空间一个是FROM空间(使用空间)一个是TO空间(闲置空间),当FROM空间中的对象要满的时候,我们就开始标记将存活对象标记好后,将他们复制到闲置空间中最后再把FROM空间清空,然后再交换他们的名称。
老生代区域垃圾回收机制,之前提到的标记清除算法,不同的是使用了标记压缩算法将他们的位置整理好
因为JS是单线程语言,所以再执行垃圾回收机制的时候JS执行会被暂停,我们叫他全停顿V8机制对它进行了一些优化,垃圾回收机制支持多线程并行回收,这样的话使垃圾回收机制的时间加快了(时间变短)最大化的保证JS执行,但是这样依然会阻塞JS执行,所以就诞生了增量标记,最大的特点就是垃圾回收可以分段执行,也就是执行一段JS执行一段垃圾回收机制,他们可以交叉执行,最大化的保证了JS的执行,此处也有一个问题就是如何记录上一次标记的位置,此时就诞生了三色标记法,三色标记法就是将上次标记到的位置,我们标记为灰色,当下次执行的时候从灰色开始重新标记,同时因为V8支持并行回收,所以就可以主线程执行JS辅助线程垃圾回收机制