V8 GC的算法整理
引用计数算法
核心思想:设置引用计数,判断当前引用数是否为 0,引用关系改变时修改引用数字,引用数字为 0 时 GC 立即回收。
const user1 = { age: 11 } const user2 = { age: 22 } const user3 = { age: 33 } const nameList = [user1.age, user.age] 复制代码
优点: 即时回收垃圾对象,减少程序卡顿时间
缺点:1. 无法回收循环引用的对象 2. 资源消耗大
循环引用
function fn() { const obj1 = {} const obj2 = {} obj1.name = obj2 obj2.name = obj1 return '' } 复制代码
标记清除算法
核心思想: 分为标记和清除两个阶段完成,遍历所有对象找标记活动对象,遍历所有对象清除没有标记对象,回收相应空间。
优点:1. 可以回收循环引用对象
缺点:1.空间碎片化 2.不会即时回收垃圾对象
标记整理算法
核心思想:标记算法的增强,标记阶段的操作和标记清除一致,清除整理阶段会先执行整理,移动对象位置,使地址是连续的。
优点:减少空间碎片化
缺点:不会即时回收垃圾对象
V8 垃圾回收策略
v8 采用即时编译的,内存设限
V8 采用分代回收的思想,内存分为新生代和老生代,不同区分别采用不同的 GC 算法
GC 算法(分代回收、空间复制、标记清除、标记整理、标记整理)
v8 中回收新生代对象(存活时间较短的对象)
小空间用于存储新生代对象(32M | 16M)
主要用到复制算法 + 标记整理
小空间分为 from 和 to 两块空间
活动对象存储于 from 空间
标记整理后将活动对象拷贝至 To
from 与 to 交换空间后,完成 from 空间释放
晋升
晋升就是将新生代对象移动至老生代。1.一轮 GC 还存活的新生代需要晋升;2.To 空间的使用率超过 25%,新的活动对象不够用也会晋升。
v8 中回收老生代对象(存活时间较长的对象)
老生代内存大小:64 位操作系统中 1.4G 和 32 位操作系统 700M
主要算法:标记清除、标记整理、标记增量
首先使用标记清除完成垃圾空间的回收
采用标记整理进行空间优化(晋升)
标记增量算法提升效率
标记增量:把程序的执行分为很多小块,标记和代码执行交替执行。
当数据达到 1.5G 时才采用标记增量。
老生代与新生代对比
新生代区域垃圾回收使用空间换时间(复制算法)
老生代数据较大不适用复制算法
作者:小楼昨夜北风
链接:https://juejin.cn/post/7028088682213015583