说一下浏览器废物收回机制?

要点: 栈废物收回、堆废物收回、重生区老生区、Scavenge算法、符号-铲除算法、符号-收拾算法、全停顿、增量符号

答:

浏览器废物收回机制根据数据的存储方法分为栈废物收回堆废物收回

栈废物收回的方法十分简洁,当一个函数履行结束之后,JavaScript 引擎会通过向下移动 ESP 来销毁该函数保存在栈中的履行上下文,遵循先进后出的准则。

堆废物收回,当函数直接结束,栈空间处理完成了,可是堆空间的数据尽管没有被引用,可是还是存储在堆空间中,需要废物收回器将堆空间中的废物数据收回。

为了使废物收回达到更好的效果,根据目标的生命周期不相同,运用不同的废物收回的算法。在 V8 中会把堆分为重生代和老生代两个区域,重生代中寄存的是生计时间短的目标,老生代中寄存的生计时间久的目标。重生区中运用Scavenge算法老生区中运用符号-铲除算法符号-收拾算法


Scavenge算法: 1. 符号:对目标区域中的废物进行符号 2. 铲除废物数据和收拾碎片化内存:副废物收回器会把这些存活的目标仿制到闲暇区域中,并且有序的排列起来,仿制后闲暇区域就没有内存碎片了 3. 人物翻转:完成仿制后,目标区域与闲暇区域进行人物翻转,也便是本来的目标区域变成闲暇区域,本来的闲暇区域变成了目标区域,这样就完成了废物目标的收回操作,一起这种人物翻转的操作还能让重生代中的这两块区域无限重复运用下去

符号-铲除算法: 1. 符号:符号阶段便是从一组根元素开端,递归遍历这组根元素,在这个遍历进程中,能抵达的元素称为活动目标,没有抵达的元素就可以判断为废物数据。 2. 铲除:将废物数据进行铲除。 3. 产生内存碎片:对一块内存多次履行符号 – 铲除算法后,会产生大量不接连的内存碎片。而碎片过多会导致大目标无法分配到足够的接连内存。

符号-收拾算法 1. 符号:和符号 – 铲除的符号进程相同,从一组根元素开端,递归遍历这组根元素,在这个遍历进程中,能抵达的元素符号为活动目标。 2. 收拾:让一切存活的目标都向内存的一端移动 3. 铲除:整理掉端鸿沟以外的内存 V8 是运用副废物收回器和主废物收回器处理废物收回的,不过由于 JavaScript 是运行在主线程之上的,一旦履行废物收回算法,都需要将正在履行的 JavaScript 脚本暂停下来,待废物收回结束后再康复脚本履行。我们把这种行为叫做全停顿。 为了降低老生代的废物收回而造成的卡顿,V8 将符号进程分为一个个的子符号进程,一起让废物收回符号和 JavaScript 应用逻辑交替进行,直到符号阶段完成,我们把这个算法称为增量符号(Incremental Marking)算法