V8垃圾回收策略主要基于
分代式垃圾回收机制
。现代的垃圾回收算法中按对象的存活时间将内存的垃圾回收进行不同的分代,然后分别对不同分代的内存施以更高效的算法。
V8的内存分代:
在V8中,主要将内存分为新生代和老生代,新生代内存 存储的为存活时间较短的对象,老生代内存存储的为存活时间较长或常驻内存的对象,如下图:
V8堆的整体大小就是新生代所用内存空间加上老生代的内存空间。
V8新生代算法(Scavenge):
在分代基础上,新生代中的对象主要通过Scavenge算法进行垃圾回收。在Scavenge的具体实现中,主要采用了Cheney算法
Cheney算法是一种采用复制的方式实现的垃圾回收算法。它将堆内存一分为二,每一部分空间称为semispace。在这两个semispace空间中,只有一个处于使用中,另一个处于闲置状态。处于使用状态的semispace空间称为From空间,处于闲置状态的空间称为To空间。
当我们分配对象时,先是在From空间中进行分配。当开始进行垃圾回收时,会检查From空间中的存活对象,这些存活对象将被复制到To空间中,而(From空间内的)非存活对象占用的空间将会被释放。完成复制后,From空间和To空间的角色发生对换(即以前的From空间释放后变为To;To空间在复制存活的对象后,变为From空间)。简而言之,在垃圾回收过程中,就是通过将存活对象在两个semispace空间之间进行复制。
- Scavenge的缺点:
只能使用堆内存中的一半
,这是由划分空间和复制机制所决定的。
- Scavenge的优点:
Scavenge由于只复制存活的对象,并且对于生命周期短的场景存活对象只占少部分,所以它**在时间效率上有优异的表现。** **Scavenge是典型的牺牲空间换取时间的算法,
** 所以无法大规模地应用到所有的垃圾回收中。但可以发现,Scavenge非常适合应用在新生代中,因为新生代中对象的生命周期较短,恰恰适合这个算法。
- 晋升:
实际使用的堆内存是新生代的两个semispace空间大小和老生代所用内存大小之和。当一个对象经过多次复制依然存活时,它将会被认为是生命周期较长的对象。这种较长生命周期的对象随后会被移动到老生代中,采用新的算法进行管理。对象从新生代中移动到老生代中的过程称为晋升。
在单纯的Scavenge过程中,From空间中的存活对象会被复制到To空间中去,然后对From空间和To空间进行角色对换(又称翻转)。但在分代式垃圾回收前提下,From空间中的存活对象在复制到To空间之前需要进行检查。在一定条件下,需要将存活周期长的对象移动到老生代中,也就是完成对象晋升。
- 晋升条件:
对象晋升的条件主要有两个,一个是对象是否经历过Scavenge回收,一个是To空间的内存占用比超过25%限制。
- 设置25%这个限制值的原因:
当这次Scavenge回收完成后,这个To空间将变成From空间,接下来的内存分配将在这个空间中进行。如果占比过高,会影响后续的内存分配。 对象晋升后,将会在老生代空间中作为存活周期较长的对象来对待,接受新的回收算法处理。
V8老生代算法(Mark-Sweep && Mark-Compact):
对于老生代中的对象,由于存活对象占较大比重,再采用Scavenge的方式会有两个问题:一个是存活对象较多,复制存活对象的效率将会很低;另一个问题依然是浪费一半空间的问题。为此,V8在老生代中主要采用Mark-Sweep和Mark-Compact相结合的方式进行垃圾回收。
Mark-Sweep:
Mark-Sweep是标记清除的意思,它分为标记和清除两个阶段。与Scavenge相比,Mark-Sweep并不将内存空间划分为两半,所以不存在浪费一半空间的行为。与Scavenge复制活着的对象不同,Mark-Sweep在标记阶段遍历堆中所有对象,并标记活着的对象,在随后的清除阶段中,只清除没有被标记的对象。
-.-
可以看出,Scavenge中只复制活着的对象,而Mark-Sweep只清理死亡对象。
活对象在新生代中只占较小部分,死对象在老生代中只占较小部分,这是两种回收方式能高效处理的原因。
下图为Mark-Sweep在老生代空间中标记的示意图,黑色部分标记为死亡对象
Mark-Sweep最大的问题:
在进行一次标记清除回收后,内存空间会出现不连续的状态。这种内存碎片会对后续的内存分配造成问题,因为很可能出现**需要分配一个大对象的情况,这时所有的碎片空间都无法完成此次分配,就会提前触发垃圾回收,而这次回收是不必要的。(注意理解这句话,不要把内存想象成液体.而是固体,就像一个个散乱排列的麻将,需要进行排序处理–即后面要讲的
Mark-Compact)**
Mark-Compact:
为了解决Mark-Sweep的内存碎片问题,Mark-Compact被提出来。Mark-Compact是标记整理的意思,是在Mark-Sweep的基础上演变而来的。它们的差别在于对象在标记为死亡后,在整理的过程中,将活着的对象往一端移动,移动完成后,直接清理掉边界外的内存。
下图为Mark-Compact完成标记并移动存活对象后的示意图,白色格子为存活对象,深色格子为死亡对象,浅色格子为存活对象移动后留下的空洞。
完成移动后,就可以直接清除最右边的存活对象后面的内存区域完成回收。
Mark-Sweep、Mark-Compact、Scavenge三种主要垃圾回收算法的简单对比
| 回收算法 | Mark-Sweep | Mark-Compact | Scavenge |
| — | — | — | — |
| 速度 | 中等 | 最慢 | 最快 |
| 空间开销 | 少(有碎片) | 少(无碎片) | 双倍空间(无碎片) |
| 是否移动对象 | 否 | 是 | 是 |
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
![](https://i-blog.csdnimg.cn/blog_migrate/bded577f21b5174aac5242920f407f36.jpeg)
最后
前端校招精编面试解析大全点击这里免费获取完整版pdf查看
容对你有帮助,可以扫码获取!!(备注:前端)**
![](https://i-blog.csdnimg.cn/blog_migrate/bded577f21b5174aac5242920f407f36.jpeg)
最后
前端校招精编面试解析大全点击这里免费获取完整版pdf查看