垃圾回收机制
MDN上有说: 从2012年起,所有现代浏览器都使用了
标记-清除垃圾
回收算法。所有对于js垃圾回收算法的改进都是基于标记-清除算法的改进
「什么是垃圾:」 一般来说,没有
被引用
的对象就是垃圾,就是要才清除的。但有个例外,如果几个对象相互引用形成一个环,但根访问不到他们,他们也是垃圾(引用计数法,无法清除他们)
「垃圾回收的几种算法:」
1-1引用计数法
概念: 记录有多少“程序”在引用自己,当引用的数值为0时,就开始清除它。
优势:
- 可
马上
回收垃圾,当被引用数值为0
时,对象马上会把自己作为空闲空间
连到空闲链表
上,也就是说。在变成垃圾的时候就立刻
被回收。 - 因为是即时回收,那么‘程序’不会暂停去单独使用很长一段时间的GC,那么
最大暂停
时间很短
。 - 不用去遍历堆里面的所有活动对象和非活动对象
劣势:
- 计数器需要
占很大
的位置
,因为不能预估被引用的上限,打个比方,可能出现32位即2的32次方个对象同时引用一个对象,那么计数器就需要32位。 - 最大的劣势是
无法解决循环引用
无法回收的问题 这就是前文中IE9之前出现的问题
1-2 标记清除法
主要将GC的垃圾回收过程分为两个阶段
标记阶段:把所有活动
对象做上标记
。
清除阶段:把没有
标记(也就是非活动对象)销毁
。
优势:
- 实现简单,打标记也就是打或者不打两种可能,所以就一位二进制位就可以表示
- 解决了循环引用问题
缺点
- 造成碎片化(有点类似磁盘的碎片化)
- 再分配时遍次数多,如果一直没有找到合适的内存块大小,那么会遍历空闲链表(保存堆中所有空闲地址空间的地址形成的链表)一直遍历到尾端
5、1-3 复制算法
- 将一个内存空间分为两部分,一部分是
From
空间,另一部分是To
空间 - 将
From空间
里面的活动
对象复制
到To空间
- 释放掉整个
From
空间 - 再将From空间和To空间的身份
互换
,那么就完成了一次GC。