v8垃圾回收机制

1、为何需要垃圾回收

在v8引擎执行js代码的过程中,当遇到函数的情况时,会为其创建一个函数执行的上下文,并添加到调用堆栈的栈顶,函数的作用域中包含了该函数中声明的所以变量,当函数执行完毕后,对面的执行上下文会从栈顶弹出,函数的作用域随之销毁,其包括的所以变量也会统一释放并自动回收。如果不回收,必然导致内存暴增,引发内存泄漏。

2、v8引擎的内存限制

由于js的单线程机制和垃圾回收机制,
V8引擎为了减少对应用的性能造成的影响,采用了一种比较粗暴的手段,那就是直接限制堆内存的大小,毕竟在浏览器端一般也不会遇到需要操作几个G内存这样的场景

3、v8的垃圾回收策略

V8的垃圾回收策略主要是基于分代式垃圾回收机制,其根据对象的存活时间将内存的垃圾回收进行不同的分代,然后对不同的分代采用不同的垃圾回收算法。

v8的内存结构

主要了解新生代和老生代

  • 新生代(new_space):大多数的对象开始都会被分配在这里,这个区域相对较小但是垃圾回收特别频繁,该区域被分为两半,一半用来分配内存,另一半用于在垃圾回收时将需要保留的对象复制过来。(Scavenge算法)
  • 老生代(old_space):新生代中的对象在存活一段时间后就会被转移到老生代内存区,相对于新生代该内存区域的垃圾回收频率较低。老生代又分为老生代指针区和老生代数据区,前者包含大多数可能存在指向其他对象的指针的对象,后者只保存原始数据对象,这些对象没有指向其他对象的指针。Mark-Sweep(标记清除)和Mark-Compact(标记整理)

4、如何避免内存泄漏

  • 尽可能少地创建全局变量
  • 手动清除定时器
  • 少用闭包
  • 清除DOM引用
  • 弱引用
    在ES6中为我们新增了两个有效的数据结构WeakMap和WeakSet,就是为了解决内存泄漏的问题而诞生的。其表示弱引用

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!