JavaScript 的垃圾回收机制
主要垃圾回收算法
1.标记清除算法:从根对象(全局对象、当前函数调用栈等)开始,递归遍历所有可达对象并标记为"活动",然后这种清除,通俗来讲就是从根部出发可以找到的变量不清除,解决了俩个变量相互引用导致内存泄露的问题,而且是自动管理内存
2.引用计数法:每个对象维护一个引用计数器,记录有多少引用指向它,当他的引用次数为0的时候就清除该变量,而这种方法有个很大的缺点就是无法解决循环引用(就算函数已经执行完,相互引用的变量引用次数仍不为0),会导致内存泄露,现在很少使用这种方法。
3.Scavenge 算法:这种算法网课中并未提到,这种算法就是占用俩个空间一个叫from space,一个叫to speace,首先所有新生代分配到from space,当其空间快满时触发回收,然后从根对象开始遍历对象图,标记存活对象,把存活对象复制到to speace,同时更新对他们的引用,回收完成后二者角色互换,等待下一次触发。
这种算法的优点就是不会产生内存碎片
如果某个对象经历多次回收依旧存活,则该对象晋升为老生代
垃圾回收机制的优化
1.分代回收(Generational Collection):
将内存分为俩种(1)新生代(Young Generation), 这个用来存放新创建的对象,而这个对象一般存活时间也短就比如局部变量,这种变量的回收既频繁也快速,使用的算法是Scavenge 算法频繁回收。
老生代(Old Generation):存放存活时间较长的对象,使用 标记-清除/标记-整理 算法
2.增量标记(Incremental Marking)
传统标记清除的缺点是全停顿和延迟问题,而增量标记很好地解决了这些问题
工作原理:
三色标记法:V8 使用 白、灰、黑 三种颜色标记对象状态:白色:未被访问(初始状态,可能为垃圾),灰色:已被访问,但子对象未被递归标记(待处理),黑色:已被完全标记,所有子对象已检查(确定存活)。
增量标记流程:
初始标记(Initial Marking)(短时间阻塞):从 GC Roots(全局变量、执行栈等)直接引用的对象标记为 灰色。
增量标记(Incremental Marking)(分步执行):每次从灰色队列取出少量对象,递归标记其子对象:子对象若为白色,则标记为 灰色(加入队列)。当前对象标记为 黑色。执行一段时间后暂停,让主线程运行 JavaScript 代码。
最终标记(Final Marking)(短时间阻塞):处理剩余的灰色对象,确保所有可达对象被标记。
回收阶段:增量标记完成后,触发 清除(Sweep) 或 整理(Compact) 阶段(可并行或延迟执行)。
这就是js垃圾回收机制的一些知识是 的拓展