高性能 JavaScript 引擎 V8 - 垃圾回收

566次阅读  |  发布于3年以前

JavaScript 是一门具有自动垃圾收集机制的编程语言,由执行环境负责在代码执行时管理内存,当运行 javascript 时,你需要一个引擎来处理它,无论是在浏览器还是在 node.js 环境中, V8是你的选择之一,也一定是你的不二选择。下面我们就一起来看看V8是怎么进行高效的垃圾回收的吧。

垃圾数据是怎么产生的

 let test = new Object()
 test.a = new Array(10)

当 JavaScript 执行这段代码的时候,会先在全局作用域中添加一个 test 变量,并在堆中创建了一个空对象,将该对象的地址指向了 test。

随后又创建一个大小为 10 的数组,并将属性地址指向了 test.a。此时的内存布局图如下所示:

如果此时,我将另外一个对象赋给了 a 属性,代码如下所示:

test.a = new Object()

那么此时的内存布局如下所示:

我们可以看到,a 属性之前是指向堆中数组对象的,现在已经指向了另外一个空对象,那么此时堆中的数组对象就成为了垃圾数据,因为我们无法从一个根对象遍历到这个 Array 对象,那么此时数组对象就成了垃圾数据。

垃圾回收算法

垃圾回收的实现简单分为以下三个步骤:

第一步:可访问性

从 GC Roots 对象出发,遍历 GC Root 中的所有对象:

浏览器环境中,GC Root 有很多,通常包括了以下几种 (但是不止于这几种):全局的 window 对象(位于每个 iframe 中);文档 DOM 树,由可以通过遍历文档到达的所有原生 DOM 节点组成;存放栈上变量。

第二步:回收不可访问对象所占据的内存

第三步:内存整理

以上就是大致的垃圾回收的流程。目前 V8 采用了两个垃圾回收器,主垃圾回收器和副垃圾回收器,下面我们再具体来看看两个回收器是怎么回收垃圾的。

副垃圾回收器和主垃圾回收器

副垃圾回收器

主垃圾回收器

优化垃圾回收器

接下来我们一起来看下具体这几种技术是怎么优化的。

并行回收

增量回收

并发回收

在实际的应用中,这三种回收机制通常是融合在一起用的。

参考资料

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8