V8 内存浅析

☆樱花仙子☆ 提交于 2020-01-16 06:26:24

总结

  1. V8 使用 c++ 开发,主要应用于 Google chrome 和 node.js 中。

  2. 内存构成为:

  • new space:大多数对象,小,回收频繁
  • old space:只保存原始数据对象,没有指向其它对象的指针
  • large object space:有自己的内存,不会移动大对象区
  • code space:代码对象,唯一拥有执行权限的内存
  • map:cell 和 map,每个区域都存放同样大小的元素,结构简单
  1. 内存清理优化:GC 会停止其它响应操作,V8 优化:先将变量存到 new space,new space 存满后,将 ns 的活跃区和非活跃区调换,清理非活跃区,超过两次未清理的变量加入到 old space,其它没超过两次的替换到活跃区。old space 满了,用标记清除,清除从根开始无法访问的变量。

V8 内存浅析

V8 是谷歌开发的高性能 JavaScript 引擎,该引擎使用 C++ 开发。目前主要应用在 Google Chrome 浏览器和 node.js 当中。

V8 内存构成

一个 V8 进程的内存通常由以下几个块构成:

  • 新生代内存区(new space): 大多数的对象都会被分配在这里,这个区域很小但是垃圾回收比较频繁;
  • 老生代内存区(old space): 属于老生代,这里只保存原始数据对象,这些对象没有指向其他对象的指针;
  • 大对象区(large object space): 这里存放体积超越其他区大小的对象,每个对象有自己的内存,垃圾回收不会移动大对象区;
  • 代码区(code space): 代码对象,会被分配在这里。唯一拥有执行权限的内存;
  • map 区(map space): 存放 Cell 和 Map,每个区域都是存放相同大小的元素,结构简单。

v8

其中带斜纹的是对应的内存块中未使用的内存空间。new space 通常很小(1~8M),它被分成了两部分,一部分叫做 inactive new space,一部分是激活状态,为啥会有激活和未激活之分的原因,下面会提到。old space 偏大,可能达几百兆。

v8 内存生命周期

假设代码中有一个对象 jerry ,这个对象从创建到被销毁,刚好走完了整个生命周期,通常会是这样一个过程:

  1. 这个对象被分配到了 new space;
  2. 随着程序的运行,new space 塞满了,gc 开始清理 new space 里的死对象,jerry 因为还处于活跃状态,所以没被清理出去;
  3. gc 清理了两遍 new space,发现 jerry 依然还活跃着,就把 jerry 移动到了 old space;
  4. 随着程序的运行,old space 也塞满了,gc 开始清理 old space,这时候发现 jerry 已经没有被引用了,就把 jerry 给清理出去了。

第二步中,清理 new space 的过程叫做 Scavenge,这个过程采用了空间换时间的做法,用到了 inactive new space,过程如下:

  1. 当活跃区满了之后,交换活跃区和非活跃区,交换后活跃区变空了;
  2. 将非活跃区的两次清理都没有清理出去的对象移到 old space;
  3. 将还没清理够两次的但是活跃状态的对象移动到活跃区。

第四步中,清理 old space 的过程叫做 Mark-sweep 标记清除,这块占用内存很大,所以没有使用 Scavenge,这个回收过程包含了若干次标记过程和清理过程:

  1. 标记从根(root)可达的对象为黑色;
  2. 遍历黑色对象的邻接对象,直到所有对象都标记为黑色;
  3. 循环标记若干次;
  4. 清理掉非黑色的对象。
    简单来说,Mark-sweep 就是把从根节点无法获取到的对象清理掉了

本文参考:V8 内存浅析

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!