<-Home
浏览器垃圾回收♻️机制
垃圾数据、变量声明周期
此时将另一个对象赋值给a属性:
dog.a = new Object();
a的指向改变了,此时堆中的数组对象就成了不被使用的数据,专业名次叫做不可达的数据;
V8 GC 算法
一、标记
- 从根节点(Root)出发,遍历所有的对象;
- 可以遍历到的对象,是可达的(reachable);
- 没有遍历到的对象,不可达的(unreachable);
全局变量window,DOM 树, 存放在栈中的变量。。。是根节点,不可能被回收;
二、清理 在完成所有的标记之后,统一处理内存中所有不可达的对象;
三、内存整理
- 在频繁回收对象后,内存中就会存在大量不连续空间,专业名词叫【内存碎片】;
- 当内存中出现了大量内存碎片之后,如果需要分配较大的连续内存时,就有可能出现内存不足的情况;
- 某些垃圾回收器是不会产生碎片的,不需要内存整理;
GC 时间
浏览器进行垃圾回收的时候,会暂停js脚本的执行,回收完成之后再继续执行js脚本;对于连贯性要求比较高的应用,这种机制会有很大的影响,比如游戏、动画等;
一、分代收集
- 临时对象【函数作用内部变量、块级作用域变量】,这类对象需要快速回收
- 长久对象【全局window、DOM、Web API】,这类对象可以放慢回收
这两种对象对应的回收机制不同,所有 V8把堆分为新生代和老生代两个区域,前者存放临时对象,后者存放长久对象; 并且让副垃圾回收器、主垃圾回收器,分别负责新生代、老生代的垃圾回收。
二、主垃圾回收器
负责老生代垃圾回收,有以下两个特点:
- 对象占用空间大
- 对象存活时间长
它使用 【标记->清除算法】
- 首相是标记
- 从一组跟元素开始,递归遍历这一组跟元素
- 在这个遍历过程中,能达到的元素称为活动对象,没有达到的元素可以判断为垃圾数据;
-
然后是垃圾清除
直接将标记为垃圾的数据清理掉;
- 多次标记-清除🆑操纵后,会产生大量不连续的内粗碎片🧩,接下来就需要进行内存整理;
三、副垃圾回收器
负责新生代垃圾的回收,通常只支持1~8M的容量;新生代被分为两个区域:一半是对象区,一般是空闲区域;
- 先给对象区域所有所有垃圾标记
- 标记完成之后,存活的对象被复制到空闲区,并进行一次有序的排列;
副垃圾回收器没有内存碎片整理就是因为空闲区的对象都是有序的,没有碎片存在,也就不需要整理;
- 复制完成之后,对象区和空闲区会进行对调。将空闲区的对象放入对象区里面;
以上就完成了垃圾回收。
因为副垃圾回收器执行频繁,所以考虑到执行效率,一般新生区的空间都会被设置很小,一旦监测到空间满了就立即执行垃圾回收操作;