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
Tags: