Javascript 垃圾收集机制介绍理解


Posted in Javascript onMay 14, 2013

经常使用 Javascript 的人会琢磨其垃圾收集机制,Javascript 并不像 C,C++ 那样需要开发者手动去清除垃圾,在编写 Javascript 程序是,开发者无需关心内存使用问题,所需内存分配以及无用内存(垃圾)的回收完全实现了自动管理。究其根源,主要是程序收集那些不再使用的变量,并且释放其占用的内存。因此,垃圾收集机制会按照固定时间间隔,周期性反复的执行这一操作。

举例来说,局部变量只存在于函数内部,程序会为局部变量在栈内存或堆内存中分配对应的存储空间,当函数运行结束,局部变量所占用的内存就没有存在的必要了,这时程序会释放局部变量所占用的内存供其他变量使用。这是程序最简单释放内存的方法,但是很多时候,程序中变量会一直被使用,此时垃圾收集机制必须跟踪变量并且判断其是否被使用,是否可以释放其内存空间。

垃圾收集机制主要判断变量释放内存空间的方法有两个:其一是标记清除法,其二是引用计数法。

标记法,每个变量都有其运行环境,变量创建后会在某种环境中运行,比如创建一个局部变量,局部变量会运行在函数体内。当函数运行时,会标记局部变量为“进入环境”,当函数体运行结束后,意味着变量脱离了其运行环境,此时则将变量标记为“离开环境”。对于“离开环境”的变量,垃圾收集机制会进行相应记录,并且在下一个回收周期时将其释放。

引用计数法,跟踪记录每个值的被引用次数。声明一个变量并将一个引用类型值赋给该变量时,这个值得引用次数就是 1。如果同一个值又被赋给另外一个变量,则该值的引用次数加 1。相反,如果包含对这个值的引用的变量又取得另外一个值,这个值得引用次数减 1。当这个值得引用次数为 0 时,则说明没有办法再访问到此值,因此就可以将其占用的内存空间回收。当垃圾收集器在下一个周期运行时,会释放引用次数为零的值所占用的内存空间。(原文解释参考:Javascript 高级程序设计 - 第二版)

举个例子来说:

            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;

对比上面的例子,举一个正常情况下的例子。
            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,在下一个垃圾收集周期时,会被回收并且释放其所占用的内存。
Javascript 相关文章推荐
JavaScript中this关键字使用方法详解
Mar 08 Javascript
javascript之水平横向滚动歌词同步的应用
May 07 Javascript
RGB颜色值转HTML十六进制(HEX)代码的JS函数
Apr 25 Javascript
FF IE兼容性的修改小结
Sep 02 Javascript
jQuery动态添加与删除tr行实例代码
Oct 18 Javascript
使用JS读取XML文件的方法
Nov 25 Javascript
Angular实现点击按钮后在上方显示输入内容的方法
Dec 27 Javascript
vue的toast弹窗组件实例详解
May 14 Javascript
小程序兼容安卓和IOS数据处理问题及坑
Sep 18 Javascript
JS实现头条新闻的经典轮播图效果示例
Jan 30 Javascript
js实现无限层级树形数据结构(创新算法)
Feb 27 Javascript
uniapp,微信小程序中使用 MQTT的问题
Jul 11 Javascript
JavaScript实现GriwView单列全选(自写代码)
May 13 #Javascript
jquery实现漂浮在网页右侧的qq在线客服插件示例
May 13 #Javascript
js 程序执行与顺序实现详解
May 13 #Javascript
JS/jQuery实现默认显示部分文字点击按钮显示全部内容
May 13 #Javascript
JS 加入收藏夹的代码(主流浏览器通用)
May 13 #Javascript
jQuery实现长文字部分显示代码
May 13 #Javascript
jq选项卡鼠标延迟的插件实例
May 13 #Javascript
You might like
重量级动漫纷纷停播!唯独OVERLORD第四季正在英魂之刃继续更新
2020/05/06 日漫
php将12小时制转换成24小时制的方法
2015/03/31 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
2015/07/03 PHP
php实现xml转换数组的方法示例
2017/02/03 PHP
php字符串截取函数mb_substr用法实例分析
2019/06/25 PHP
PHP下载文件函数与用法示例
2019/09/27 PHP
Javascript面象对象成员、共享成员变量实验
2010/11/19 Javascript
jQuery Ajax 仿AjaxPro.Utility.RegisterTypeForAjax辅助方法
2011/09/27 Javascript
js 日期比较相关天数代码
2014/04/02 Javascript
JavaScript 面向对象与原型
2015/04/10 Javascript
bootstrap模态框关闭后清除模态框的数据方法
2018/08/10 Javascript
微信小程序实现分享朋友圈的图片功能示例
2019/01/18 Javascript
echarts统计x轴区间的数值实例代码详解
2019/07/07 Javascript
记录vue做微信自定义分享的一些问题
2019/09/12 Javascript
ES2020 新特性(种草)
2020/01/12 Javascript
vue 实现根据data中的属性值来设置不同的样式
2020/08/04 Javascript
Python实现带参数的用户验证功能装饰器示例
2018/12/14 Python
python web自制框架之接受url传递过来的参数实例
2018/12/17 Python
python实现读取excel文件中所有sheet操作示例
2019/08/09 Python
详解python模块pychartdir安装及导入问题
2020/10/22 Python
Stylenanda中文站:韩国一线网络服装品牌
2016/12/22 全球购物
Sunglasses Shop英国:欧洲领先的太阳镜在线供应商之一
2018/09/19 全球购物
美国最大的电子宠物训练产品制造商:PetSafe
2018/10/12 全球购物
Linux常见面试题
2013/03/18 面试题
西安夏日科技有限公司Java笔试题
2013/01/11 面试题
主办会计岗位职责
2014/03/13 职场文书
公务员保密承诺书
2014/03/27 职场文书
让生命充满爱演讲稿
2014/05/10 职场文书
关于青春的演讲稿三分钟
2014/08/22 职场文书
竞选学习委员演讲稿
2014/09/01 职场文书
2014年质量工作总结
2014/11/22 职场文书
因身体原因离职的辞职信范文
2015/05/12 职场文书
2016年三八节红领巾广播稿
2015/12/17 职场文书
2016党校学习心得体会
2016/01/07 职场文书
HTML速写之Emmet语法规则的实现
2021/04/07 HTML / CSS
教你用Python写一个植物大战僵尸小游戏
2021/04/25 Python