作者:Herbert 文章内容输出来源:拉勾教育大前端高薪训练营课程
整体概述
V8的垃圾回收采用分代回收策略,分代回收策略将内存分为新生代区和老生代区,新生代区又分为From区和To区。
当触发垃圾回收机制时:
在新生代区,先在From区使用标记整理策略进行垃圾回收,再将From区复制到To区,然后将From区内存释放,这时如果有需要,再对To区进行晋升操作(将新生代区对象转移到老生代区),最后交换From区与To区,完成新生代区垃圾回收;
在老生代区,如果新生代区发生晋升且老生代区空间不足时采用标记整理策略,否则使用标记清除策略,回收过程中使用增量标记和惰性清理提高效率。
这样就完成了一轮垃圾回收。
概念解释
- 分代回收:
- 概念:将内存分为新生代和老生代两个区域,对不同区域采取不同的回收策略。
- 新生代:
- 概念:存活时间较短对象的存储区域
- 内存分配:内存:32位16M,64位32M
- 分区:将内存平均分为两个区
- From区:正在使用的空间
- To区:空闲的空间
- 注意:
- 最开始会将所有对象都存入新生代
- 如果开始新生代内存空间不够,直接分配到老生代
- 老生代:
- 概念:存活时间较长对象的存储区域,一般为新生代晋升而来
- 内存分配:内存:32位700M,64位1.4G
- 新生代:
- 晋升
- 概念:新生代对象转移到老生代区域
- 触发条件:
- 一个对象发生了一定次数的从From到To
- To区域内存占比超过25%之后
- 概念:将内存分为新生代和老生代两个区域,对不同区域采取不同的回收策略。
- 标记清除:
- 过程:
- step1:遍历内存中所有对象,并对可达对象进行标记
- step2:遍历内存中所有对象,对未标记对象进行内存释放,已标记对象进行标记清除
- 优点:可以回收循环引用的对象
- 缺点:
- 标记对象的清除使内存不连续,从而浪费空间
- 需要循环遍历时才进行内存释放,时效性差
- 过程:
- 标记整理:(标记清除+整理)
- 过程:
- step1:遍历内存中所有对象,并对可达对象进行标记
- step2:遍历内存中所有对象,对已标记对象先进行整理(整理为连续区域),再进行标记清除,对未标记对象进行内存释放
- 过程:
- 可达对象:从根触发可以访问到的对象(根可以理解为全局)
- 增量标记/惰性清理:
- 概念:将标记/清理过程碎片化,使程序执行与对象标记/清理可以交替进行
- 回收步骤:
- step1:遍历+标记直接可达对象
- step2:时间上分段,对对象进行标记
- step3:时间上分段,对对象进行标记清除和空间释放
- 内存限制:
- 概述:V8对内存进行了限制,32位系统为800M,64位系统为1.5G.
- 原因:
- 这种内存大小对web应用已经足够
- 内存再大一些,垃圾回收时间会影响用户体验