Document

2020-09-29

V8引擎

认识V8:

  • V8是一款主流的JS执行引擎
  • V8采用即时编译 所以速度很快
  • V8有内存设限 32位是不超过800MB 64位是不超过1.5GB
  • 值类型的数据存在栈里由系统回收 一般我们说的垃圾回收都是回收堆里的 也就是复杂数据类型

V8回收策略:

  • V8采用分代回收的思想
  • 内存分为新生代存储区、老生代存储区 两种
  • 为了区分新生代老生代 V8内存空间一分为二 左侧存储新生代 右侧存储老生代
  • 针对不同种类对象采用不同的算法 以达到最高效的处理

V8常用的GC算法:

  • 分代回收 新生代和老生代
  • 空间复制 From空间复制到To
  • 标记清除 
  • 标记整理
  • 标记增量

新生代对象的垃圾回收:

  • 小空间用于存储新生代对象 64位最大32MB 32位最大16MB
  • 新生代对象指的是存活时间较短的对象 例如某函数局部作用域中的一些变量
  • 回收过程采用复制算法+标记整理
  1. 将新生代内存也分成两个大小相等的空间
  2. 使用空间为From,空闲空间为To
  3. 活动对象存储于From空间中 To一直是空闲的
  4. 当From空间应用到一定程度之后 触发GC操作
  5. 标记整理后将活动对象拷贝到To空间中
  6. From空间全部释放 然后与To空间交换就完成了垃圾回收

新生代对象回收细节:

  • 拷贝过程中有可能出现晋升
  • 晋升:指的是将新生代对象移动至老生代进行存储
  • 一般 一轮GC后 还存活的新生代对象需要晋升 考虑到并不是存活时间短
  • 如果To空间的使用率超过25% 那么这些对象也需要晋升
  • 因为如果To空间使用率过大 当To变成From后 有可能没有多少剩余内存留给新进来的数据了

老生代对象的垃圾回收:

  • 大空间用于存储老生代对象 64位最大1.4GB 32位最大700MB
  • 老生代对象指的是存活时间较长的对象 例如全局下的一些变量 或者是闭包中的变量
  • 回收过程采用 标记清除+标记整理+标记增量算法
  1. 首先 主要是 使用标记清除完成垃圾空间的回收
  2. 当有新生代晋升 且老生代内存块不足以存储晋升的数据时 触发标记整理 整理碎片化的内存
  3. 采用增量标记进行效率优化
  4. 增量标记:标记过程会阻塞代码执行 所以将整个标记过程分成很多次交替的插在执行过程中去标记

总结对比:

  • 新生代区域的垃圾回收是 使用空间换时间 因为每时每刻都有一般空闲空间的存在 通过复制清除的方式快速清理垃圾
  • 老生代区域垃圾回收不适合复制算法 因为老生代的内存很大 且数据多 复制浪费时间 浪费内存