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
- 新生代对象指的是存活时间较短的对象 例如某函数局部作用域中的一些变量
- 回收过程采用复制算法+标记整理
- 将新生代内存也分成两个大小相等的空间
- 使用空间为From,空闲空间为To
- 活动对象存储于From空间中 To一直是空闲的
- 当From空间应用到一定程度之后 触发GC操作
- 标记整理后将活动对象拷贝到To空间中
- From空间全部释放 然后与To空间交换就完成了垃圾回收
新生代对象回收细节:
- 拷贝过程中有可能出现晋升
- 晋升:指的是将新生代对象移动至老生代进行存储
- 一般 一轮GC后 还存活的新生代对象需要晋升 考虑到并不是存活时间短
- 如果To空间的使用率超过25% 那么这些对象也需要晋升
- 因为如果To空间使用率过大 当To变成From后 有可能没有多少剩余内存留给新进来的数据了
老生代对象的垃圾回收:
- 大空间用于存储老生代对象 64位最大1.4GB 32位最大700MB
- 老生代对象指的是存活时间较长的对象 例如全局下的一些变量 或者是闭包中的变量
- 回收过程采用 标记清除+标记整理+标记增量算法
- 首先 主要是 使用标记清除完成垃圾空间的回收
- 当有新生代晋升 且老生代内存块不足以存储晋升的数据时 触发标记整理 整理碎片化的内存
- 采用增量标记进行效率优化
- 增量标记:标记过程会阻塞代码执行 所以将整个标记过程分成很多次交替的插在执行过程中去标记
总结对比:
- 新生代区域的垃圾回收是 使用空间换时间 因为每时每刻都有一般空闲空间的存在 通过复制清除的方式快速清理垃圾
- 老生代区域垃圾回收不适合复制算法 因为老生代的内存很大 且数据多 复制浪费时间 浪费内存