zoukankan      html  css  js  c++  java
  • js垃圾回收机制

    本文参考链接:https://segmentfault.com/a/1190000018605776?utm_source=tag-newest

    一、首先明确什么是垃圾?

    那些没有被任何变量或者属性引用的对象就是垃圾,哪怕几个对象形成一个环形引用,但如果根访问不到他们,那也算是垃圾。

    二、理解js内存的可达性机制

    js的可达性,简单说就是那些可以以某种方式访问到可用的值,这样的值会被保存在内存中。

    如果某个值可以通过引用或者引用链被根访问到,那么这个值就是可访问的

    举例子:

    一个引用:

    // user 具有对象的引用
    let user = {
      name: "John"
    };

     箭头表示对象引用,全局变量“user”引用对象 {name:“John”},所以这个对象会被保存在内存中,user的值被覆盖引用会丢失

    user = null;

     现在john变成了不可达状态,没办法引用访问,所以垃圾回收器将john丢弃,释放内存。

    两个引用:

    // user具有对象的引用
    let user = {
      name: "John"
    };
    
    let admin = user;

     这种情况下,user = null,对象还是可以引用的。

    相互关联的对象:

    function marry (man, woman) {
      woman.husban = man;
      man.wife = woman;
    
      return {
        father: man,
        mother: woman
      }
    }
    
    let family = marry({
      name: "John"
    }, {
      name: "Ann"
    })

    函数 marry 通过给两个对象彼此提供引用来“联姻”它们,并返回一个包含两个对象的新对象

    产生内存结构

     目前所有对象都是可访问的

    试着删除两个引用

     此时仍然都是可访问的

     但是如果我们把这两个都删除,那么我们可以看到 John 不再有传入的引用:

    垃圾回收之后:

                              图片描述

    无法访问的数据块:

     

    三、内部算法:

    1、标记-清除

    这是当前主流的GC算法,V8里面就是用这种。当对象,无法从根对象沿着引用遍历到,即不可达(unreachable),进行清除。

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

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

    简单说就是从根开始逐个访问,根能访问到的就标记,根访问不到的就是垃圾,要被清除。

    例如,对象结构如下:

    图片描述

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

    第一步标记根

    图片描述

    然后标记他们的引用

    图片描述

    以及子孙代的引用:

    图片描述

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

    图片描述

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

    一些优化:

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

     2、引用计数

    另一种不太常见的垃圾回收策略是引用计数。引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减1。当这个引用次数变成0时,则说明没有办法再访问这个值了,因而就可以将其所占的内存空间给收回来。这样,垃圾收集器下次再运行时,它就会释放那些引用次数为0的值所占的内存。

    不积跬步无以至千里
  • 相关阅读:
    扑克牌顺子
    多任务Multitask Learning
    智能指针
    左旋转字符串
    和为s的两个数字
    07.极简主义读后感
    06.极简主义——汇流(笔记)
    05.极简主义——奉献(笔记)
    04.极简主义——热情(笔记)
    03.极简主义——人际关系(笔记)
  • 原文地址:https://www.cnblogs.com/lyt0207/p/12022859.html
Copyright © 2011-2022 走看看