资讯专栏INFORMATION COLUMN

javascript垃圾回收机制 - 标记清除法/引用计数/V8机制

JellyBool / 3753人阅读

摘要:例如,和中的对象就是实现的对象,而对象的垃圾收集机制采用的是引用计数策略。因此,即使中的引擎使用标记清除策略实现,但是访问的对象依然是基于引用计数策略的。垃圾回收器从不移动大对象。

Js GC原理:

找出那些不再继续使用的变量,然后释放其所占用的内存,垃圾回收器会按照固定的时间间隔周期性地执行这一操作

Js GC 策略:

标记清除法

引用计数

JavaScript 内存分配:

定义变量时就完成了内存分配,还可以通过函数调用分配内存,使用值的过程实际上是对分配内存进行读取与写入的操作

标记清除法:

标记方式:特殊位的反转、维护一个列表

原理:垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后它会去掉环境中的变量已经被环境中变量被标记为引用的变量,在此之后再被标记的变量将被视为准备删除的变量。最后垃圾回收器清除标记的变量,回收它们所占用的内存空间

目前主流浏览器都是使用标记清除式的垃圾回收策略,只不过收集的间隔有所不同

引用计数:

原理:每次引用加一,被释放时减一,当这个值的引用次数变成 0 时,就可以将其内存空间回收

缺点:循环引用(obj1 和 obj2 通过各自的属性相互引用,也就是说,这两个对象的引用次数都是 2)

IE兼容问题

在 IE9 之前,IE 中有一部分对象并不是原生 JavaScript 对象。例如,BOM 和 DOM 中的对象就是 C++ 实现的 COM 对象,而 COM 对象的垃圾收集机制采用的是引用计数策略。因此,即使 IE 中的 JavaScript 引擎使用标记清除策略实现,但是 JS 访问的 COM 对象依然是基于引用计数策略的。可以在 IE 中涉及到 COM 对象,就会存在循环引用的问题

解决:将变量设置为 null

V8内存机制

V8 引擎会限制 JavaScript 所能使用的内存大小

性能问题:(运行时间间隔)

IE7 之前的垃圾收集器是根据内存分配量运行的,达到某一个临界值就是启动垃圾回收器

缺点:如果该脚本在其生命周期需要一直保持这么多变量,垃圾回收器就不得不频繁运行。

浏览器可自动触发: window.CollectGarbage()

避免:执行代码中只保留必要的数据,一旦数据不再有用,通过设置为 null 来释放其引用(适用于大多数全局变量和全局对象的属性)

V8 的堆构成

新生区:大多数对象被分配在这里。新生区是一个很小的区域,垃圾回收在这个区域非常频繁,与其他区域相独立。

老生指针区:这里包含大多数可能存在指向其他对象的指针的对象。大多数在新生区存活一段时间之后的对象都会被挪到这里。

大对象区:这里存放体积超越其他区大小的对象。每个对象有自己 map 产生的内存。垃圾回收器从不移动大对象。
-代码区:代码对象,也就是包含 JIT 之后指令的对象,会被分配到这里。这是唯一拥有执行权限的内存区(不过如果代码对象因过大而放在大对象区,则该大对象所对应的内存也是可执行的。译注:但是大对象内存区本身不是可执行的内存区)。
-Cell 区、属性 Cell 区、Map 区:这些区域存放 Cell、属性 Cell 和 Map,每个区域因为都是存放相同大小的元素,因此内存结构很简单

分代回收

原因:绝大多数对象的生存期很短,只有某些对象的生存期较长

过程:

1、对象起初会被分配在新生区(通常很小,只有 1-8 MB)在新生区的内存分配非常容易:我们只需保有一个指向内存区的指针,不断根据新对象的大小对其进行递增即可。当该指针达到了新生区的末尾,就会有一次清理(小周期),清理掉新生区中不活跃的死对象。

2、活跃超过 2 个小周期的对象,则需将其移动至老生区老生区在标记-清除或标记-紧缩(大周期)的过程中进行回收。大周期进行的并不频繁。一次大周期通常是在移动足够多的对象至老生区后才会发生。至于足够多到底是多少,则根据老生区自身的大小和程序的动向来定。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/109792.html

相关文章

  • JS专题之垃圾回收

    摘要:如果没有引用指向该对象零引用,对象将被垃圾回收机制回收。经过增量标记改进后,垃圾回收的最大停顿时间可以减少到原来的左右。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。 前言 在讲 JS 的垃圾回收(Garbage Collection)之前,我们回顾上一篇《JS专题之memoization》,memoization 的原理是以参数作为 key,函数结果作为 v...

    liujs 评论0 收藏0
  • Node(V8)的垃圾回收机制

    摘要:基本概念垃圾回收机制。对两个不同生代的不同垃圾回收策略构成了整个的垃圾回收机制。此种方式会导致下一次内存中产生大量碎片,即内存空间不连续,导致内存分配时面对大对象可能会无法满足,提前出发下一次的垃圾回收机制。 : 聊一聊垃圾回收机制吧。 : 恩,垃圾回收是自动的。 基本概念 GC(Garbage collection)垃圾回收机制。目的是解释器去判别需要回收的内容,当解释器认为一个占...

    suxier 评论0 收藏0
  • V8引擎】浅析Chrome V8引擎中的垃圾回收机制和内存泄露优化策略

    摘要:一前言的垃圾回收机制使用垃圾回收机制来自动管理内存。垃圾回收器只会针对新生代内存区老生代指针区以及老生代数据区进行垃圾回收。分别对新生代和老生代使用不同的垃圾回收算法来提升垃圾回收的效率。 V8 实现了准确式 GC,GC 算法采用了分代式垃圾回收机制。因此,V8 将内存(堆)分为新生代和老生代两部分。 一、前言 V8的垃圾回收机制:JavaScript使用垃圾回收机制来自动管理内存。垃...

    qingshanli1988 评论0 收藏0
  • JavaScript 垃圾回收

    摘要:根据的定义,垃圾回收是一种自动的内存管理机制。但在没有结束前,回调函数里的变量以及回调函数本身都无法被回收。在内存泄漏部分,我们讨论了无意的全局变量会带来无法回收的内存垃圾。 根据 Wiki 的定义,垃圾回收是一种自动的内存管理机制。当计算机上的动态内存不再需要时,就应该予以释放,以让出内存。直白点讲,就是程序是运行在内存里的,当声明一个变量、定义一个函数时都会占用内存。内存的容量是有...

    BothEyes1993 评论0 收藏0
  • 【进阶1-4期】JavaScript深入之带你走进内存机制

    摘要:引擎对堆内存中的对象进行分代管理新生代存活周期较短的对象,如临时变量字符串等。内存泄漏对于持续运行的服务进程,必须及时释放不再用到的内存。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第一期,本周的主题是调用堆栈,今天是第4天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了解本进阶计划...

    不知名网友 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<