前端面试宝典---js垃圾回收机制
什么是垃圾回收
垃圾回收是指一种自动内存管理机制,当声明一个变量时,会在内存中开辟一块内存空间用于存放这个变量。当这个变量被使用过后,可能再也不需要它了,此时垃圾回收器会自动检测并回收这些不再使用的内存空间。垃圾回收的主要目的是释放不再使用的内存,提高内存的使用效率,避免内存泄漏。
垃圾回收的两种算法
标记清除算法
标记清除算法的工作过程可以分为两个阶段:
标记阶段
:从根对象(在JS中就是全局对象)开始,遍历所有可达的对象,并标记它们。
清除阶段
:清除所有未被标记的对象,这些对象被认为是"垃圾",可以被安全地回收。
这个过程可以想象成从根部溢出一大桶油漆,油漆流经所有引用并标记所有可达的对象。然后移除未被标记的对象
引用计数算法
引用计数算法的工作原理如下:
- 每当有一个新的引用指向该对象时,计数加一。
- 当引用被删除或重新赋值时,计数减一。
- 当计数为零时,表示该对象不再被任何其他对象引用,可以被安全地回收。
引用计数算法的优点是能够在对象变成垃圾的那一刻立即回收,不需要等待定期扫描。然而,它无法处理对象之间的循环引用问题,容易导致内存泄漏
两种算法比较
标记清除算法和引用计数算法各有优缺点:
标记清除算法:
优点:能够处理对象之间的循环引用问题
缺点:可能导致性能问题,需要定期扫描整个内存空
引用计数算法:
优点:能够在对象变成垃圾的那一刻立即回收
缺点:无法处理对象之间的循环引用问题,容易导致内存泄漏
V8引擎的垃圾回收机制
分代式垃圾回收机制将内存分为新生代和老生代两部分:
新生代:处理短期存活的对象,内存最大值在64位系统和32位系统上分别为32MB和16MB。新生代又会分为两个半区(from和to两个区)
老生代:处理长期存活的对象。
新生代垃圾回收
当新生代的from空间快达到上限时,会触发一次垃圾回收。垃圾回收器会从根部开始遍历,不可达对象(即无法遍历到的对象)将会被回收,并把空间中的剩余对象移动到to空间。最后把from空间清空。
此时to空间变成新的from空间,from空间变成新的to空间。
新生代=》老生代
如果对象在新生代中存活了一定次数(通常是15次),它会被晋升到老生代。
老生代垃圾回收
当老生代的内存空间快达到上限时,V8引擎使用标记-清除(Mark-Sweep)、标记-压缩(Mark-Compact)算法。
- 把老生代所有的对象标记成0,并把可达的对象标记成1
- 清除0的对象
- 把剩余的对象标记置0
- 并用标记-压缩算法将位置重新排序变得紧密