• 关于JS垃圾回收机制


    一、垃圾回收机制的必要性

           由于字符串、对象和数组没有固定大小,所以当它们的大小已知时,才能对它们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便它们能够被再用,否则,JavaScript的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。

      JavaScript的解释器可以检测到何时程序不再使用一个对象了,当它确定了一个对象是无用的时候,它就知道不再需要这个对象,可以把它所占用的内存释放掉了。

    二、垃圾回收机制

      Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。

    1、标记清除(常用) 

      当一块内存中的数据能够被访问时,垃圾回收器就认为"该数据能够被获得"。不能够被获得的数据,就会被打上标记,并回收内存空间。这种方式叫作标记---清除算法。

    这个算法会设置一个全局对象,并定期地从全局对象开始查找,垃圾回收器会找到所有可以获得与不能获得的数据。

      工作流程:

       (1)垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。

       (2)去掉环境中的变量以及被环境中的变量引用的变量的标记。

       (3)再被加上标记的会被视为准备删除的变量。

       (4)垃圾回收器完成内存清除工作,销毁那些带标记的数据并回收它们所占用的内存空间。

      注意:在局部作用域中,当函数执行完毕后,局部变量也就没有存在的必要了,因此垃圾收集器很容易做出判断并回收。但在全局中,变量什么时候需要自动释放内存空间则很难判断,因此我们在开发时,应尽量避免使用全局变量。如果使用了全局变量,则建议不再使用它时,通过释放变量方式,以确保能够及时回收内存空间。

    2、引用计数

      跟踪记录每个值被引用的次数。例当变量声明,第一次赋值时记为1,然后当这个变量值改变时,记录为0,将计数为0的回收。

      工作流程:

       (1)声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。

       (2)同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.

       (3)当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.

       (4)当引用次数变成0时,说明没办法访问这个值了。

       (5)当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。  

    但是当循环引用的时候就会释放不掉内存。

    1 function problem() {
    2     var objA = new Object();
    3     var objB = new Object();
    4 
    5     objA.someOtherObject = objB;
    6     objB.anotherObject = objA;
    7 }

    当objA和objB通过各自的属性相互引用,也就是说这两个对象的引用次数都是2。在采用引用计数的策略中,由于函数执行之后,这两个对象都离开了作用域,函数执行完成之后,objA和objB还将会继续存在,因为他们的引用次数永远不会是0。这样的相互引用如果说很大量的存在就会导致大量的内存泄露。

    因为IE中的BOM、DOM的实现使用了COM,而COM对象使用的垃圾收集机制是引用计数策略。所以会存在循环引用的问题。

    解决:手工断开js对象和DOM之间的链接,赋值为null。IE9把DOM和BOM转换成真正的JS对象了,所以避免了这个问题。

     

  • 相关阅读:
    go开发实战
    mq的各种问题分析(顺序,一致性,重复,丢失,堆积)
    神经图灵机(NTM)
    手机号隐藏
    验证指定项
    js姓名隐藏
    iview rate 评分验证
    校验成功后,提示文字不消失
    iview 开始时间不能大于结束时间
    [PHP] Laravel 获取模型/表的所有字段
  • 原文地址:https://www.cnblogs.com/guanhx/p/12654718.html
Copyright © 2020-2023  润新知