总结
-
V8 使用 c++ 开发,主要应用于 Google chrome 和 node.js 中。
-
内存构成为:
new space
:大多数对象,小,回收频繁old space
:只保存原始数据对象,没有指向其它对象的指针large object space
:有自己的内存,不会移动大对象区code space
:代码对象,唯一拥有执行权限的内存map
:cell 和 map,每个区域都存放同样大小的元素,结构简单
内存清理优化
: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,每个区域都是存放相同大小的元素,结构简单。
其中带斜纹的是对应的内存块中未使用的内存空间。new space 通常很小(1~8M),它被分成了两部分,一部分叫做 inactive new space,一部分是激活状态,为啥会有激活和未激活之分的原因,下面会提到。old space 偏大,可能达几百兆。
v8 内存生命周期
假设代码中有一个对象 jerry ,这个对象从创建到被销毁,刚好走完了整个生命周期,通常会是这样一个过程:
- 这个对象被分配到了 new space;
- 随着程序的运行,new space 塞满了,gc 开始清理 new space 里的死对象,jerry 因为还处于活跃状态,所以没被清理出去;
- gc 清理了两遍 new space,发现 jerry 依然还活跃着,就把 jerry 移动到了 old space;
- 随着程序的运行,old space 也塞满了,gc 开始清理 old space,这时候发现 jerry 已经没有被引用了,就把 jerry 给清理出去了。
第二步中
,清理 new space 的过程叫做 Scavenge
,这个过程采用了空间换时间的做法,用到了 inactive new space,过程如下:
- 当活跃区满了之后,交换活跃区和非活跃区,交换后活跃区变空了;
- 将非活跃区的两次清理都没有清理出去的对象移到 old space;
- 将还没清理够两次的但是活跃状态的对象移动到活跃区。
第四步中
,清理 old space 的过程叫做 Mark-sweep 标记清除
,这块占用内存很大,所以没有使用 Scavenge,这个回收过程包含了若干次标记过程和清理过程:
- 标记从根(root)可达的对象为黑色;
- 遍历黑色对象的邻接对象,直到所有对象都标记为黑色;
- 循环标记若干次;
- 清理掉非黑色的对象。
简单来说,Mark-sweep 就是把从根节点无法获取到的对象清理掉了
。
本文参考:V8 内存浅析
来源:CSDN
作者:wenxiaowen677
链接:https://blog.csdn.net/waiting677/article/details/103994983