原文:从头开始学JavaScript (十)——垃圾收集

一、垃圾收集

1.1javascript垃圾收集机制:

自动垃圾收集,执行环境会负责管理代码执行过程中的使用的内存。而在C和C++之类的语言中,开发人员的一项基本任务就是手动跟踪内存的使用情况,这是造成许多问题的一个根源。在编写javascript程序时候,开发人员不用再关心内存使用的问题,所需内存的分配 以及无用的回收完全实现了自动管理。

1.2垃圾收集原理:

  • 找出那些不再继续使用的变量,然后释放其中占用的内存。
  • 垃圾收集器会按照固定的时间间隔(或代码执行中预设的收集时间),周期性的执行这一操作。

1.3垃圾收集方法:

1.3.1标记清除:当变量进入环境时标记“进入环境”,而当变量离开环境时,这将其 标记为“离开环境”。

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

例如:

         function countMethod(){
var object1 = new Object(); // 声明变量,计数器由 0 变为 1
var object2 = new Object(); // 声明变量,计数器由 0 变为 1
object1.method1 = "This is object1"; // object1 计数器 -1,object1 读数变为0
object2.method2 = "This is object2"; // object2 计数器 -1,object2 读数变为0
}

当函数运行结束后,object1 object2的读数均为 0,在下一个垃圾收集周期时,会被回收并且释放其所占用的内存。

可以把引用计数想象成猴子掰玉米,玉米的使用权是变量(之所以是使用权而不是玉米本身,是因为引用计数是对引用类型值而言的),猴子是计数器。第一个猴子拿到玉米使用权,计数器+1;第二个猴子来和第一个猴子分享玉米的使用权,计数器+2;其中一个猴子发现一个更大的玉米的使用权,放弃这个玉米的使用权,计数器—1,另一个猴子也发现一个更大的玉米的使用权,放弃这个玉米的使用权,计数器就变成0,这个玉米就被回收了~(例子举得不恰当还望见谅,只是帮助理解~)

再看下面一个例子:

             function countMethod(){
var object1 = new Object(); // 声明变量,计数器由 0 变为 1
var object2 = new Object(); // 声明变量,计数器由 0 变为 1
object1.method1 = object2; // object1 计数器 -1,object2 计数器 +1
object2.method2 = object1; // object1 计数器 +1,object2 计数器 -1
}

这个例子就相当于两个猴子都分别有一个玉米使用权,但是总觉得对方手里的玉米的使用权所对应的玉米比自己大,所以不停地在交换玉米的使用权。也就是循环引用。(例子举得不恰当还望见谅,只是帮助理解~)

此函数运行退出后,object1 的计数器读数为 1,object2 的计数器度数为 1。所以两个变量都不会被销毁。如果大量的这样的程序存在于函数体内,就会导致大量的内存被浪费而无法回收,从而导致内存的泄露。

上述问题可以通过手动释放 object1 object2 所占用的内存来消除。即

                  object1.method1 = null;
object2.method2 = null;

二、性能问题

垃圾收集器都是周期性运行的,而且如果为变量分配的内存数量很客观,那么回收工作量也是相当大的。在这种情况下,确定垃圾收集的时间间隔是一个非常重要的问题。说到垃圾收集器多长时间运行一次,不禁让人联想到IE因此声名狼藉的性能问题。IE的垃圾收集器是根据内存分配量运行的,具体一点说就是256个变量、4096个对象(或数组)字面量和数组元素(slot)或者64KB的字符串。达到上述任何一个临界值,垃圾收集器就会运行。这种实现的问题在于,如果一个脚本中包含那么多变量,那么该脚本很可能会在其生命周期中一直保持那么多的变量。而这样一来,垃圾收集器就可能不得不频繁的运行。结果,由此引发的严重性能问题初始IE7重写了其垃圾收集例程。

【上面这段话可以这么理解:垃圾收集器可以看做是勤劳的环卫工人,内存分配量可以看做是垃圾箱的容积,如果一个小区的居民造垃圾的能力是单位时间恒定的,也就是说每个回收周期都能把垃圾箱堆满,那么环卫工人会累趴的。。。】(例子举得不恰当还望见谅,只是帮助理解~)

随着IE7的发布,其javascript引擎的垃圾收集例程改变了工作方式:触发垃圾收集的变量分配、字面量和(或)数组元素的临界值被调整为动态修正。IE7中的各项临界值在初始化时与IE6相等。如果例程回收的内存分配量低于15%,则变量 、字面量和(或)数组元素的临界值就会加倍。如果例程回收了85%的内存分配量,则将各种临界重置会默认值。这一看似简单的调整,极大地提升了IE在运行包含大量javascript的页面时的性能。

事实上,在有的浏览器中可以触发垃圾收集过程,但不建议这样做。在IE中,调用window.CollectGarbage()方法会立即指向垃圾收集,在Opera7及更高版本中,调用widnow.opera.collect()也会启动垃圾收集例程。

三、管理内存

确保占用最少内存可以让页面获得更好的性能,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用(dereferencing)。这一做法是用于大多数全局变量和全局对象的属性。局部变量会在他们执行环境时自动被解除引用,如下面这个例子所示:

 function createPerson (name) {
var localPerson = new Object();
localPerson.name = name;
return localPerson;
};
var gllbalPerson = createPerson("Nicholas"); // 手工解除globalPerson的引用
globalPerson = null;

最后一 行代码就是解除引用。

解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

就相当于你把垃圾从家里拿出来扔到小区的垃圾桶,垃圾只是脱离了你家这个执行环境,但是并未被垃圾场回收,只有等下一个打扫周期,勤劳的环卫工人用垃圾车拉走到垃圾场,才算是将其回收。(例子举得不恰当还望见谅,只是帮助理解~)

从头开始学JavaScript (十)——垃圾收集的更多相关文章

  1. 从头开始学JavaScript (十二)——Array类型

    原文:从头开始学JavaScript (十二)--Array类型 一.数组的创建 注:ECMAscript数组的每一项都可以保存任何类型的数据 1.1Array构造函数 var colors = ne ...

  2. 从头开始学JavaScript (十一)——Object类型

    原文:从头开始学JavaScript (十一)--Object类型 一.object类型 一个object就是一系列属性的集合,一个属性包含一个名字(属性名)和一个值(属性值). object对于在应 ...

  3. 从头开始学JavaScript (九)——执行环境和作用域

    原文:从头开始学JavaScript (九)--执行环境和作用域 一.执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有与之关联的变量对象. 变量对象:保存着环境中 ...

  4. 从头开始学JavaScript (八)——变量

    原文:从头开始学JavaScript (八)--变量 一.变量分类: 基本类型值:null.undefined.number.string.Boolean: 引用类型值:保存在内存中的对象,如:Obj ...

  5. 从头开始学JavaScript (七)——函数

    原文:从头开始学JavaScript (七)--函数 一.return 函数在执行完return之后停止并立即退出. return返回值:与return: 如下两个例子: function sum(n ...

  6. 从头开始学JavaScript (六)——语句

    原文:从头开始学JavaScript (六)--语句 一.条件分支语句:if 基本格式: if (<表达式1>){    <语句组1>}else if (<表达式2> ...

  7. 从头开始学JavaScript (五)——操作符(二)

    原文:从头开始学JavaScript (五)--操作符(二) 一.乘性操作符 1.乘法:*      乘法操作符的一些特殊规则: 如果操作数都是数值,按照常规的乘法计算,如果乘积超过了ECMAscri ...

  8. 从头开始学JavaScript (四)——操作符

    原文:从头开始学JavaScript (四)--操作符 一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: <script typ ...

  9. 从头开始学JavaScript (二)——变量及其作用域

    原文:从头开始学JavaScript (二)--变量及其作用域 一.变量 ECMAscript变量是松散型变量,所谓松散型变量,就是变量名称可以保存任何类型的数据,每个变量仅仅是一个用于保存值的占位符 ...

随机推荐

  1. emeditor 配置教程

    1.众多的图形界面配置功能 通过查看EmEditor的安装目录,可以发现,EmEditor有几个配置文件,理论上应该可以通过修改配置文件来达到配置EmEditor的目 的.然而,打开配置文件一看,如果 ...

  2. iis虚拟目录引发的路径问题

    在iis上把web程序配置成站点是ok的,但配置成虚拟目录,就会发现 图片路径不能,样式不能加载,链接出错. 解决方案: 1,上传图片  ~/upload 2,cs程序,链接跳转,请用~/index. ...

  3. hdu 5101 Select(Bestcoder Round #17)

    Select                                                    Time Limit: 4000/2000 MS (Java/Others)     ...

  4. Datatable转换为Json 然后,Json数据导入 js 档

    C#在里面Datatable转换为Json的5代码示例 /// <summary> /// Datatable转换为Json /// </summary> /// <pa ...

  5. 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern)

    原文:乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 访问者模式(Visitor Pattern) 作者:webabc ...

  6. GitLab 安装配置笔记(转)

    GitLab的安装方式 GitLab的两种安装方法: 编译安装 优点:可定制性强.数据库既可以选择MySQL,也可以选择PostgreSQL;服务器既可以选择Apache,也可以选择Nginx. 缺点 ...

  7. 猫学习IOS(四)UI半小时就搞定Tom猫

    阿土 首先对影响 下载项目的源材料: Tom猫游戏代码iOS 素材http://blog.csdn.net/u013357243/article/details/44457357 效果图 以前风靡一时 ...

  8. Python 获得Facebook用户有一个共同的兴趣Friends

    CODE: #!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-8-13 @author: guaguastd @name: c ...

  9. overflow的几个坑

    在android 4.0的原生浏览器上注意: html元素上不要加overflow: auto;的样式,否则会造成有些元素无法点击 在absolute元素上 不要加 overflow: auto; 否 ...

  10. mysql5.6设置主从报错1236,Increase max_allowed_packet on master,原因却是Binlog偏移量不对

    在试Mysql5.6,搭了个主从: CHANGE MASTER TO MASTER_HOST='1.2.3.4', master_user='slave', master_password='xxxq ...