V8 引擎
- V8 是一款主流的JavaScript执行引擎(Chrome、Nodejs都采用这这个引擎)
- V8 采用即时编译
- V8 内存设置上限(64bit不超过1.5G,32bit不超过800M)
这个内存上限对于网页应用来说足够,而且垃圾回收的足够快可以提升用户体验。
V8 垃圾回收策略
在程序的使用过程中,会用到很多的数据,这些数据可以分为原始数据和对象类型的数据,对于基础的原始数据都是由程序的语言自身来控制的,所以这里说的回收主要指的时当前堆里的对象数据,所以这个过程时离不开内存操作的。
- 采用分代回收的思想(是由V8 内存设限决定的)
- 内存分为新生代和老生代
- 针对不同对象采用同的GC算法
V8 中常用GC算法
- 分代回收
- 空间复制
- 标记清除
- 标记整理
- 标记增量
V8 如何回收新生代对象
V8 内存分配
- V8 内存一分为二
- 小空间用于存储新生代对象(32M | 16M)(64bit | 32bit)
- 新生代指的是存活时间较短的对象
新生代对象回收实现
- 回收过程采用复制算法+标记整理
- 新生代内存二等分
- 使用空间为 From ,空闲空间为 To
- 活动对象存储于 From 空间
- 标记整理后将活动对象拷贝至 To
- From 与 To 交换空间完成释放
回收细节说明(好多疑问呀,得细品)
- 拷贝过程可能出现晋升
如果拷贝时发现某一个变量对象所使用的空间再当前的老生代对象里面也会出现,这个时候就会出现所谓的晋升的操作。
-
晋升就是将新生代对象移动至老生代
-
一轮 GC 还存活的新生代需要晋升(这样的话岂不是说全都变成老年代了?)
-
To 空间的使用率超过 25%
V8 老生代对象回收
老生代对象说明
- 老生代对象存放在右侧老生代区域
- 64bit => 1.4G, 32bit => 700M
- 老生代对象就是指存活时间较长的对象
老年代对象回收实现
- 主要采用标记请除、标记整理、增量标记算法
- 首先使用标记请除完成垃圾空间的回收
- 采用标记整理进行空间优化
- 采用增量标记进行效率优化
当新生代对象往老年代对象空间进行移动的时候,如果出现了空间不足就会进行标记整理,以整理碎片空间供晋升对象使用。
细节对比
-
新生代区域垃圾回收使用空间换时间(还是因为新生代本身的区域本就很小,所以带来的空间浪费和时间的收益来比是微不足道的)
-
老生代区域垃圾回收不适合复制算法(一是老生代占用的空间往往比较大,使用复制算法会浪费大量的空间,而是数据多复制算法复制的时间就多,还会消耗很多时间资源)
增量标记
垃圾回收的时候会阻塞当前JS程序的执行。
标记增量就是将整个垃圾回收操作拆分成一段一段的形式,组合地完成整个垃圾回收。
这样做的好处,减少垃圾回收阻塞程序带来的负面影响。充分的利用时间和空间资源。
整个 V8 最大的垃圾回收,即当它达到1.5G的时候,采用分增量标记的方式去进行垃圾回收用的时间也不会超过一秒钟。