zoukankan      html  css  js  c++  java
  • Javascript高级编程学习笔记(11)—— 垃圾回收机制

    垃圾回收机制

    垃圾回收机制,是保证脚本能长时间运行的重要机制

    JS具有自动垃圾收集机制,也就是说执行环境会负责管理代码执行过程中使用的内存

    与一些偏底层的语言(c、c++)不同,我们不需要手工地去管理内存的使用情况

    因为JS替我们完成了需要内存的分配,以及无用内存的回收,然后释放其占用的内存。

    其原理其实很简单,就是找出那些不再使用的内存释放掉就行,所以垃圾收集器会按照固定时间间隔来执行该操作

    垃圾回收是针对局部变量的,因为全局变量会在浏览器关闭后自动释放内存,而局部变量不同,其只会在函数执行期间存在

    所以垃圾收集器的主要任务是为那些无用的变量打上标记,以便释放其占用的内存

    具体实现通常有以下两个策略:

    标记清除

    这是JS中最常用的垃圾收集方式,主要有以下两个步骤:

    1.当变量进入环境时将其标记为“进入环境”(从逻辑上来说永远不能释放进入环境的变量,因为随时可能会用到)

    2, 当变量离开环境时,标记为“离开环境”

    然后在垃圾收集器运行时,会将所有变量打上标记,然后去掉环境中的变量被环境引用的变量的标记

    在上述操作完成后,清除那些被标记的变量的内存

    引用计数

    另外一种垃圾回收策略就是引用计数

    什么意思呢?

    就是说跟踪每一个值被引用的次数

    这个次数怎么计算呢?

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

    如果同一个值又被赋值给另一个变量,则这个值的引用次数加一

    相反如果包含对这个值引用的变量取得了另一个值,那么这个值引用的次数就减一

    当这个值的引用次数变为0时,就意味着这个值没有变量可以访问了,就可以释放该值的内存了

    但是这一策略存在着许多问题

    1.循环引用

    即两个对象互相引用,导致引用次数始终为2,从而始终无法回收该内存

    如下所示:

    function problem(){
        var objectA = new Object();
        var objectB = new Object();
    
    
        objectA.other = objectB;
        objectB.other = objectA;
    
    }

    这样的情况就会导致两个对象都无法被回收

    2.IE中虽然JS是标记清除策略,但一些BOM、DOM对象是基于C++的组件对象模型实现的

    该对象模型是计数策略,所以在IE中只要涉及这些对象的,都会存在循环引用的问题

    PS.该问题在IE9被修复

    在有的浏览器中可以手动触发垃圾收集进程

    IE:window.collectGarbage()

    Opera:window.opera.collect()

    管理内存

    为了优化JS的性能

    最好手动解除不用变量的引用,这样就会被下一次运行的垃圾收集器清理

    方法是:

    将变量的值设为null

    也叫做解除引用,局部变量会自动完成这一过程

    PS.解除引用后该值的内存不会自动回收,解除引用的目的是让值脱离执行环境

    垃圾回收机制中还有一些比较复杂的情况,将在后续的文章中讲到

  • 相关阅读:
    USACO 3.3 A Game
    USACO 3.3 Camelot
    USACO 3.3 Shopping Offers
    USACO 3.3 TEXT Eulerian Tour中的Cows on Parade一点理解
    USACO 3.3 Riding the Fences
    USACO 3.2 Magic Squares
    USACO 3.2 Stringsobits
    USACO 3.2 Factorials
    USACO 3.2 Contact
    USACO 3.1 Humble Numbers
  • 原文地址:https://www.cnblogs.com/lhyxq/p/10118855.html
Copyright © 2011-2022 走看看