跳转到内容
aswind7
GitHub
Blog

V8引擎的垃圾回收机制

各大JS解释器在垃圾回收上的一些策略会有不同,本文主要介绍 谷歌V8引擎的垃圾回收机制。

一句话概括

垃圾回收就是找到内存中那些不可达、不可访问的值并清除掉。

// 这段代码中'a1' 会被回收
let a = 'a1'
a = null


// 这段代码中{} 会被回收
let o = {}
o = null


//全局变量num1不会被回收 页面关闭时才回收
var num1=1
function test(){
  // test函数在调用时会生成执行上下文,栈内存分配空间来保存声明的num2变量;
  // 函数执行完毕后,此时局部变量num2不再需要,会被回收
    let num2=1
}
test()

最常见的主要方法

目前引用计数已不再用因为缺点太明显

标记清除(最常用)

从 root (global/window)对象开始进行遍历,对能查到的对象进行标记,清除未被标记的对象。

引用计数

计算一个对象的被引用次数,如果为0 则回收; (看看有多少变量名从栈指向了堆内存里面的对象)

缺点:

  • 无法解决循环、互相引用;
  • 计数器占位置
function func() {
    const obj = {};
    const obj2 = {};
    obj.a = obj2;
    obj2.a = obj;
}
func(); 
// obj无法被回收因为还仍然被引用着

V8的垃圾回收

为了提高垃圾回收机制的效率,分为了新生代和老生代回收,他们的回收机制及频率是不同的:

新生代: 新声明的、存活时间短的对象作为新生代,采用一小块内存频率较高的快速清理

老生代: 存活时间长的对象作为老生代,很少接受检查

相关文章

https://juejin.cn/post/6981588276356317214#comment

https://willbchang.notion.site/b09066b6725a49df85b48512ab45f5c9