最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • JS 垃圾回收机制解析 | 8月更文挑战

    正文概述 掘金(代码搬运媛)   2021-08-20   448

    概述

    JS是一门具有自动垃圾回收机制的语言,开发人员不必关心内存分配和回收问题。

    JS的垃圾回收机制是为了以防内存泄漏,内存泄漏的含义就是当已经不需要某块内存时这块内存还存在着,垃圾回收机制就是间歇的不定期的寻找到不再使用的变量,并释放掉它们所指向的内存。

    JS 垃圾回收方式

    JS执行环境中的垃圾回收器怎样才能检测哪块内存可以被回收有两种方式:标记清除(mark and sweep)、引用计数(reference counting)。

    标记清除

    大部分浏览器以此方式进行垃圾回收,当变量进入执行环境(函数中声明变量)的时候,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”,在离开环境之后还有的变量则是需要被删除的变量。标记方式不定,可以是某个特殊位的反转或维护一个列表等。

    垃圾收集器给内存中的所有变量都加上标记,然后去掉环境中的变量以及被环境中的变量引用的变量的标记。在此之后再被加上的标记的变量即为需要回收的变量,因为环境中的变量已经无法访问到这些变量。

    核心思想:给当前不使用的值加上标记,然后再回收其内存。

    这样解释可能不容易理解,下面介绍一种简易理解的方法:

    可达性

    JavaScript 中内存管理的主要概念是可达性。

    简单地说,“可达性” 值就是那些以某种方式可访问或可用的值,它们被保证存储在内存中。

    1. 有一组基本的固有可达值,由于显而易见的原因无法删除。例如:

    • 本地函数的局部变量和参数
    • 当前嵌套调用链上的其他函数的变量和参数
    • 全局变量
    • 还有一些其他的,内部的

    这些值称为根。

    2. 如果引用或引用链可以从根访问任何其他值,则认为该值是可访问的。

    例如,如果局部变量中有对象,并且该对象具有引用另一个对象的属性,则该对象被视为可达性, 它引用的那些也是可以访问的,详细的例子如下。

    JavaScript 引擎中有一个后台进程称为垃圾回收器,它监视所有对象,并删除那些不可访问的对象。

    内部算法

    基本的垃圾回收算法称为**“标记-清除”**,定期执行以下“垃圾回收”步骤:

    • 垃圾回收器获取根并**“标记”**(记住)它们。
    • 然后它访问并“标记”所有来自它们的引用。
    • 然后它访问标记的对象并标记它们的引用。所有被访问的对象都被记住,以便以后不再访问同一个对象两次。
    • 以此类推,直到有未访问的引用(可以从根访问)为止。
    • 除标记的对象外,所有对象都被删除。

    例如,对象结构如下:

    JS 垃圾回收机制解析 | 8月更文挑战

    我们可以清楚地看到右边有一个“不可到达的块”。现在让我们看看“标记并清除”垃圾回收器如何处理它。

    第一步标记根

    JS 垃圾回收机制解析 | 8月更文挑战

    然后标记他们的引用

    JS 垃圾回收机制解析 | 8月更文挑战

    以及子孙代的引用:

    JS 垃圾回收机制解析 | 8月更文挑战

    现在进程中不能访问的对象被认为是不可访问的,将被删除:

    JS 垃圾回收机制解析 | 8月更文挑战

    这就是垃圾收集的工作原理。JavaScript 引擎应用了许多优化,使其运行得更快,并且不影响执行。

    引用计数

    这种方式常常会引起内存泄漏,低版本的IE使用这种方式。机制就是跟踪一个值的引用次数,当声明一个变量并将一个引用类型赋值给该变量时该值引用次数加1,当这个变量指向其他一个时该值的引用次数便减一。当该值引用次数为0时就会被回收。

    该方式会引起内存泄漏的原因是它不能解决循环引用的问题:

    function sample(){
        var a={};
        var b={};
        a.prop = b;
        b.prop = a;
    }
    

    这种情况下每次调用sample()函数,a和b的引用计数都是2,会使这部分内存永远不会被释放,即内存泄漏。

    总结

    • 离开作用域的值将被自动标记为可回收,因此将在垃圾回收期间被删除
    • “标记清除”是目前主流的垃圾回收算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存
    • 而“引用计数”,这种算法的思想是跟踪记录所有值被引用的次数。JS引擎目前都不再使用这种算法;IE9以前有这种算法
    • 当代码中存在循环引用现象时,“引用计数”算法会导致问题
    • 解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效的回收内存,应该及时解除不再使用的全局对象,全局对象属性以及循环引用变量的引用

    优化

    • 分代回收——对象分为两组:“新对象”和“旧对象”。许多对象出现,完成它们的工作并迅速结 ,它们很快就会被清理干净。那些活得足够久的对象,会变“老”,并且很少接受检查。
    • 增量回收——如果有很多对象,并且我们试图一次遍历并标记整个对象集,那么可能会花费一些时间,并在执行中会有一定的延迟。因此,引擎试图将垃圾回收分解为多个部分。然后,各个部分分别执行。这需要额外的标记来跟踪变化,这样有很多微小的延迟,而不是很大的延迟。
    • 空闲时间收集——垃圾回收器只在 CPU 空闲时运行,以减少对执行的可能影响。

    起源地下载网 » JS 垃圾回收机制解析 | 8月更文挑战

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元