js垃圾回收
一、标记清除
js中做常用的垃圾回收机制
- 给所有变量都打上标记
- 从跟对象开始遍历,将不是垃圾的变量标记去除
- 删除所有标记的变量,回收内存
二、引用计数
保存每个资源的引用次数,当引用次数为0时,回收内存
存在问题:当两个对象互相引用的时候,会形成循环引用,导致内存无法释放
V8对垃圾回收做的优化
分代式垃圾回收
-
新生代:存活时间较短,容量较小的1-8M的对象
内部再次进行分区,分为使用区和空闲区
当使用区数据快要存满时,开始进行垃圾回收,将使用区的活动对象放到空闲区并排序,将非活动对象清理掉,同时使用区变成空闲区,空闲区变成使用区。当对象多次复制后会进入老生代;还有一种情况是复制对象占据空闲区25%的空间时,会放入老生代,避免影响后续内存分配 -
老生代:存活时间较久,容量较大的对象
老生代直接使用标记清楚
并行标记
开启多个辅助线程标记,提高速度
增量标记
将标记过程分步执行,这样执行完一步就可以交会主线程
解决方案是
-
三色标记法 黑:不需要清除
白:需要清除
灰:断点,恢复时从此开始
默认为白色,开始时从根对象开始,将可到达的对像标记为黑色,中断时将可到达的下一个对象标记为灰色,当线程重新回到标记过程时,从灰色开始遍历,没有灰色则是完成标记 -
写屏障 由于在把主线程交出去时,可能主线程会执行往黑色对象下添加对象的操作(记住默认为白色),这时该白色实际是不应该被清除的,但是无法前一个节点不是灰色,就不会遍历到了,因此一旦有黑色对象引用白色对象,就会强制标记为灰色
懒性清理
当内存不够才开始垃圾回收,并且并不是一次全部回收
并发回收
同时开启多个辅助线程进行回收