垃圾回收机制

Chrome V8 垃圾回收机制

滑动验证页面

在JavaScript中,当我们创建变量(对象,字符串等)的时候,系统会自动给对象分配对应的内存, 当系统发现这些变量不再被使用的时候,会自动释放(垃圾回收)这些变量的内存。

为什么需要

在Chrome中,v8被限制了内存的使用(64位约1.4G/1464MB , 32位约0.7G/732MB)

  • 表层原因是,V8最初为浏览器而设计,不太可能遇到用大量内存的场景
  • 深层原因是,V8的垃圾回收机制的限制(如果清理大量的内存垃圾是很耗时间,这样回引起JavaScript线程暂停执行的时间,那么性能和应用直线下降)

Chrome 垃圾回收算法

在JavaScript中,其实绝大多数的对象存活周期都很短,大部分在经过一次的垃圾回收之后,内存就会被释放掉,而少部分的对象存活周期将会很长,一直是活跃的对象,不需要被回收。为了提高回收效率,V8 将堆分为两类新生代老生代,新生代中存放的是生存时间短的对象,老生代中存放的生存时间久的对象。 ===> 分代式垃圾回收机制

  • 新生代:生存时间较短的对象 ===> 空间小 ===> 1-8Mb ===> 副的垃圾回收器
  • 老生代:生存时间较长的对象 ===> 空间大 ====> 主的垃圾回收器

  • V8 分别使用两个主/副的垃圾回收器,以便更高效地实施垃圾回收。

新生代垃圾回收

新生代的垃圾回收算法主要通过 复制(Scavenge) 算法进行垃圾回收,该算法的流程主要是:
将堆内存一分为二,一个处于使用中 (from),一个处于闲置中 (To)。

分配内存时,会先分配到使用中的内存(from 空间),当开始进行垃圾回收的时候,回收生命周期结束的对象。

过程:

  • 标记活动对象和非活动对象
  • 复制 from space 的活动对象到 to space 并对其进行排序
  • 释放 from space 中的非活动对象的内存
  • 将 from space 和 to space 角色互换

对象晋升策略

一般在新生代申请内存,当经历一次 GC 之后如果对还存活,那么对象的年龄 +1。当年龄超过一定值(默认是 15,可以通过参数 -XX:MaxTenuringThreshold 来设定)后,如果对象还存活,那么该对象会进入老生代内存空间中(也就是晋升)。


在上面新生代垃圾回收过程中,并不是每一次都会把对象复制到闲置空间(To)中,而是在复制之前,会先判断两个条件,如果满足条件,则会触发对象晋升,而不是复制到闲置空间中。
这两个条件分别是: 

  • 是否经历过 Scavenge(复制) 回收(主要是通过内存地址判断) 
  • To 空间的内存占用比是否超过限制/回收次数 有没有到限制值 。 

两个条件达成其一即可,对象晋升后,会在老生代中被新的回收算法处理。

老生代垃圾回收

在老生代中,存活对象通常占的比重较大,所以复制的效率会相对较低,不适用 Scavenge 算法。 V8 中老生代的垃圾回收主要采用了Mark-Sweep (标记 - 清除) 和 Mark-Compact (标记 - 整理) 相结合的方式。

Mark-Sweep(标记 - 清楚)

顾名思义,Mark-Sweep 叫做标记 - 清除,它分为两个阶段:标记和清除。

  • 标记阶段,Mark-Sweep 对老生代进行第一次扫描,标记活动对象
  • 清除阶段,Mark-Sweep 对老生代进行第二次扫描,清除未被标记的对象,即清理非活动对象

可以对比出,Scavenge 只复制活着的对象,而 Mark-Sweep 只清理死亡对象。所以前者适合(复制场合少,即存活少的区域)新生代,后者适合(清理场合少,即存活多的区域)老生代。

但是 Mark-Sweep 有一个比较严重的问题,就是清除后可能会有很多内存碎片,造成这些内存空间无法合理的利用,要消除内存碎片,就需要进行内存整理。

Mark-Compact(标记 - 整理)
  • Mark-Compact 就是为了解决 Mark-Sweep 的问题而提出的。 
  • Mark-Compact,即标记 - 整理,是在标记 - 清除的基础上演变来的。它和 Mark-Sweep 的差别在于,当对象在标记为死亡后,在整理的过程中,将活着的对象往一端移动(整理),移动完成后,直接清理边界外的内存。 
  • 因为 Mark-Compact 需要移动对象再进行清除,很明显,它比 Mark-Sweep 要慢。

V8 的策略

通过上面三种算法,我们可以得出一个对比表格:

Mark-Compact 慢,Mark-Sweep 有碎片,而 V8 在取舍上结合两种:主要使用 Mark-Sweep,当空间不足以分配空间给新生代中晋升的对象时,使用 Mark-Compact 消除内存碎片。

总结

谷歌浏览器 现在是采用 分代式垃圾回收机制, 将对象分为两部分:新生代与老生代。并且对两部分使用不同的算法 

  • 新生代使用 复制(Scavenge) 算法进行垃圾回收,这种算法牺牲空间来换取时间,实际上只利用了新生代一半的空间进行存储。但优点在于面对生命周期短的对象时速度较快,而且不会产生内存碎片。 
  • 新生代中的对象 经历过多次GC之后,对象依然存在,就会进行对该对象晋升,将其 移动到老生代区域。 老生代使用 Mark-Sweep(标记 - 清楚 及 Mark-Compact(标记-整理) 两种结合。主要使用 标记清楚(Mark-Sweep),当碎片太多、不足以分配一块内存给晋升的对象时,就利用 标记整理(Mark-Compact) 进行整理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Blue_路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值