js 垃圾回收机制 + 谷歌V8引擎对垃圾回收优化

本文详细探讨了JavaScript的垃圾回收机制,包括引用计数法(及其循环引用问题)、标记清除算法(解决内存泄漏),以及V8引擎如何通过分代垃圾回收、增量垃圾回收、并行处理和缓存机制优化回收性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是垃圾回收机制

清除不在使用的对象,腾退出所占用的内存;当我们创建一个变量指向一个对象后,又给他重新赋值一个新的对象,那么原先的对象就不在使用,就可以清除。

垃圾回收的策略

1. 引用计数清除法
JavaScript使用的是基于引用计数的垃圾回收机制。当一个对象被引用时,它的引用计数加1;当一个对象的引用变成0时,说明该对象不再被使用,垃圾回收机制会自动释放该对象占用的内存。11213112312123在这里插入图片描述
缺陷:引用计数垃圾回收机制存在循环引用的问题。如果两个对象相互引用,并且没有其他地方引用它们,那么它们的引用计数永远不会变为0,导致内存泄漏。

function createObjects() {
  var obj1 = {};
  var obj2 = {};
  
  obj1.ref = obj2;
  obj2.ref = obj1;

  // 手动将obj1和obj2的引用设置为null,以帮助释放内存
  obj1 = null;
  obj2 = null;
}

在这个例子中,我们创建了两个空对象obj1和obj2。然后我们相互将它们赋值给彼此的属性ref,形成了循环引用。之后,我们将obj1和obj2的引用设置为null,期望这样可以释放内存,但实际上并不能。因为这两个对象相互引用,它们的引用计数永远不会变为0,所以垃圾回收机制无法识别它们是可以释放的对象,因此内存泄漏就会发生。

为了解决循环引用导致的内存泄漏问题,JavaScript中引入了标记清除算法,这个算法通过标记所有可以访问的对象,然后释放未被标记的对象,从而避免了循环引用带来的内存泄漏问题。

2. 标记清除法
标记清除算法通过根对象来标记所有可以访问的对象,然后将未标记的对象释放,从而解决了循环引用导致的内存泄漏问题。根对象可以是全局对象、活动函数的局部变量或者闭包中的变量。根对象可以是全局对象、活动函数的局部变量或者闭包中的变量。
缺陷:
停顿时间:在进行垃圾回收时,标记清除算法需要遍历整个对象图,并标记可达对象。遍历和标记过程通常会导致一定的停顿时间,影响应用程序的响应性能。

空间开销:标记清除算法需要维护一个标记位来表示对象是否可达,这需要占用额外的内存空间。

碎片化:标记清除算法可能导致内存碎片化的问题。当被标记的对象被清除时,它们所占用的内存空间会留下不连续的空洞。可能会限制分配大块连续内存的能力,会阻碍给新对象寻找位置。
为新的对象找位置的方式

不完全回收:标记清除算法只能回收不再可达的对象,而无法回收那些存在引用循环但仍然被使用的对象。

谷歌V8引擎对垃圾回收进行优化:

分代垃圾回收(Generational Garbage Collection):V8 引擎使用分代垃圾回收策略,将对象分为新生代老年代两部分。新生代对象通常生命周期较短,老年代对象生命周期较长。V8 使用不同的垃圾回收算法和频率来处理这两部分对象,以提高效率。

  1. 新生代(Young Generation): 新生代主要存放生命周期较短的对象,通常包括刚刚被创建的对象。这些对象经常被声明、引用,但很快就会变得不可达,需要被回收。 V8
    引擎使用了一种称为Scavenge的算法来管理新生代对象。在Scavenge过程中,对象首先被分配到From空间,当From空间满时,V8会执行垃圾回收,将仍然存活的对象复制到To空间,然后交换From和To空间的角色,以此达到清理垃圾的效果。
  2. 老年代(Old Generation): 老年代主要存放生命周期较长的对象,这些对象经过多次新生代的垃圾回收仍然存活。由于老年代内对象生命周期较长,因此需要更复杂的垃圾回收算法来管理。
    V8引擎使用了一种称为Mark-Sweep-Compact的算法来管理老年代对象。在这个算法中,首先标记所有活动对象,然后清除未标记的对象,并通过紧缩操作来减少内存碎片,以便为后续对象分配提供更大的连续内存空间。

标记-清除算法(Mark-and-Sweep Algorithm):V8 引擎使用标记-清除算法进行垃圾回收。在标记阶段,引擎会标记所有活动对象,然后在清除阶段清除未标记的对象。为了提高效率,V8 引擎使用增量标记和增量清除技术,将垃圾回收任务分解成多个阶段,避免在一次中断中清除过多内存。

增量垃圾回收(Incremental Garbage Collection):V8 引擎采用增量垃圾回收技术,将垃圾回收任务分解成多个小任务,插入到 JavaScript 代码执行之间。这样可以减少一次性的垃圾回收时间,提高系统的响应速度。
在这里插入图片描述
并行垃圾回收(Parallel Garbage Collection):因为JS 是单线程语言,所以在进行垃圾回收机制时JS的执行会被暂停即全停顿;V8 引擎在执行垃圾回收时会利用多个线程来并行处理,从而加快垃圾回收的速度。通过并行处理,可以更快地完成垃圾回收的任务,减少对应用程序的影响。
在这里插入图片描述
缓存机制(Cache Mechanisms):V8 引擎引入了一些缓存机制,如隐藏类(Hidden Classes)和行内缓存(Inline Caches),可以减少对象访问时的开销,提高访问速度,从而优化了垃圾回收过程中对象的访问和管理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值