位置: 编程技术 - 正文

全面了解JavaScirpt 的垃圾(garbage collection)回收机制(全面了解中国历史英文)

编辑:rootadmin

推荐整理分享全面了解JavaScirpt 的垃圾(garbage collection)回收机制(全面了解中国历史英文),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:全面了解自我,接纳和包容自我,全面了解中国历史看什么书,全面了解自我,接纳和包容自我,就一定能克服盲从和虚荣,全面了解中国历史看什么书,全面了解学生,全面了解婴儿发展潜质是以什么作为正确方法的,全面了解婴儿发展潜质是以什么作为正确方法的,全面了解自我,接纳和包容自我,就一定能克服盲从和虚荣,内容如对您有帮助,希望把文章链接给更多的朋友!

一、垃圾回收机制—GC

Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。

原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。

JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直至函数结束,而闭包中由于内部函数的原因,外部函数并不能算是结束。

还是上代码说明吧:

我们来看代码是如何执行的。首先定义了两个function,分别叫做fn1和fn2,当fn1被调用时,进入fn1的环境,会开辟一块内存存放对象{name: 'hanzichi', age: },而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

这里问题就出现了:到底哪个变量是没有用的?所以垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标记,以备将来收回其内存。用于标记的无用变量的策略可能因实现而有所区别,通常情况下有两种实现方式:标记清除和引用计数。引用计数不太常用,标记清除较为常用。

二、标记清除

js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

垃圾回收器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方式)。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记(闭包)。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

三、引用计数

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

Netscape Navigator3是最早使用引用计数策略的浏览器,但很快它就遇到一个严重的问题:循环引用。循环引用指的是对象A中包含一个指向对象B的指针,而对象B中也包含一个指向对象A的引用。

以上代码a和b的引用次数都是2,fn()执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为a和b的引用次数不为0,所以不会被垃圾回收器回收内存,如果fn函数被大量调用,就会造成内存泄露。在IE7与IE8上,内存直线上升。

我们知道,IE中有一部分对象并不是原生js对象。例如,其内存泄露DOM和BOM中的对象就是使用C++以COM对象的形式实现的,而COM对象的垃圾回收机制采用的就是引用计数策略。因此,即使IE的js引擎采用标记清除策略来实现,但js访问的COM对象依然是基于引用计数策略的。换句话说,只要在IE中涉及COM对象,就会存在循环引用的问题。

这个例子在一个DOM元素(element)与一个原生js对象(myObject)之间创建了循环引用。其中,变量myObject有一个名为element的属性指向element对象;而变量element也有一个属性名为o回指myObject。由于存在这个循环引用,即使例子中的DOM从页面中移除,它也永远不会被回收。

看上面的例子,有同学回觉得太弱了,谁会做这样无聊的事情,其实我们是不是就在做

这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中德变量,自然也包括obj,是不是很隐蔽啊。

解决办法

全面了解JavaScirpt 的垃圾(garbage collection)回收机制(全面了解中国历史英文)

最简单的方式就是自己手工解除循环引用,比如刚才的函数可以这样

将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾回收器下次运行时,就会删除这些值并回收它们占用的内存。

要注意的是,IE9+并不存在循环引用导致Dom内存泄露问题,可能是微软做了优化,或者Dom的回收方式已经改变

四、内存管理

1、什么时候触发垃圾回收?

垃圾回收器周期性运行,如果分配的内存非常多,那么回收工作也会很艰巨,确定垃圾回收时间间隔就变成了一个值得思考的问题。IE6的垃圾回收是根据内存分配量运行的,当环境中存在个变量、个对象、k的字符串任意一种情况的时候就会触发垃圾回收器工作,看起来很科学,不用按一段时间就调用一次,有时候会没必要,这样按需调用不是很好吗?但是如果环境中就是有这么多变量等一直存在,现在脚本如此复杂,很正常,那么结果就是垃圾回收器一直在工作,这样浏览器就没法儿玩儿了。

微软在IE7中做了调整,触发条件不再是固定的,而是动态修改的,初始值和IE6相同,如果垃圾回收器回收的内存分配量低于程序占用内存的%,说明大部分内存不可被回收,设的垃圾回收触发条件过于敏感,这时候把临街条件翻倍,如果回收的内存高于%,说明大部分内存早就该清理了,这时候把触发条件置回。这样就使垃圾回收工作职能了很多

2、合理的GC方案

1)、Javascript引擎基础GC方案是(simple GC):mark and sweep(标记清除),即:

(1)遍历所有可访问的对象。 (2)回收已不可访问的对象。

2)、GC的缺陷

和其他语言一样,javascript的GC策略也无法避免一个问题:GC时,停止响应其他操作,这是为了安全考虑。而Javascript的GC在ms甚至以上,对一般的应用还好,但对于JS游戏,动画对连贯性要求比较高的应用,就麻烦了。这就是新引擎需要优化的点:避免GC造成的长时间停止响应。

3)、GC优化策略

David大叔主要介绍了2个优化方案,而这也是最主要的2个优化方案了:

(1)分代回收(Generation GC)

这个和Java回收策略思想是一致的。目的是通过区分“临时”与“持久”对象;多回收“临时对象”区(young generation),少回收“持久对象”区(tenured generation),减少每次需遍历的对象,从而减少每次GC的耗时。如图:

这里需要补充的是:对于tenured generation对象,有额外的开销:把它从young generation迁移到tenured generation,另外,如果被引用了,那引用的指向也需要修改。

(2)增量GC这个方案的思想很简单,就是“每次处理一点,下次再处理一点,如此类推”。如图:

这种方案,虽然耗时短,但中断较多,带来了上下文切换频繁的问题。

因为每种方案都其适用场景和缺点,因此在实际应用中,会根据实际情况选择方案。

比如:低 (对象/s) 比率时,中断执行GC的频率,simple GC更低些;如果大量对象都是长期“存活”,则分代处理优势也不大。

以上这篇全面了解JavaScirpt 的垃圾(garbage collection)回收机制就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持积木网。

浅谈javascript中的加减时间 上午在处理一些js中的日期参数的时候遇到了一点问题,不晓得如何加减时间。最初的想法是自己分别取出year,month,day,hour,minute,second,然后手动

浅谈javascript中关于日期和时间的基础知识 前面的话在介绍Date对象之前,首先要先了解关于日期和时间的一些知识。比如,闰年、UTC等等。深入了解这些,有助于更好地理解javascript中的Date对象

javascript类型系统——日期Date对象全面了解 前面的话Date对象是javascript语言中内置的数据类型,用于提供日期和时间的操作接口。Date对象是在早期java中的java.util.Date类基础上创建的,为此,Date类

标签: 全面了解中国历史英文

本文链接地址:https://www.jiuchutong.com/biancheng/373544.html 转载请保留说明!

上一篇:全面理解闭包机制(如何理解闭包,闭包的优缺点)

下一篇:浅谈javascript中的加减时间(细说javascript)

  • 固定资产清理过程涉及的报表
  • 税控盘白盘和黑盘一样吗
  • 个人社保部分公司承担可以入费用吗
  • 文化事业费是什么意思
  • 百旺购货方红字信息表怎么开具
  • 一般纳税人附加税减免政策2023
  • 向境外个人支付咨询费如何算税
  • 通行费电子发票没有通行费字样
  • 具备什么条件的土地可以开发
  • 房产税收取标准有哪些
  • 个体工商户怎么注销
  • 有支出没有发票应怎么整改
  • 第三方代缴社保能查到原单位吗
  • 月初发票认证能抵扣吗
  • 预交电费有发票吗
  • 出口用的增值税税率
  • 发生销售折扣如何做账
  • 简易计税 增值税专用发票
  • 俱乐部会员有什么用
  • 公司注销增值税在借方有余额怎么处理
  • 电子发票抬头打印怎么弄
  • 一般纳税人印花税减半征收吗
  • 买车的增票可以分两次吗
  • 建筑业预交增值税最新政策
  • 母公司给子公司拨款要交税吗
  • 以银行存款支付上述材料运费480元
  • 电脑管家玩游戏卡吗
  • win11系统怎么投屏
  • ccs是什么软件
  • php文件在线解密
  • 特种商品劳务税
  • 招行网银专业版怎么登陆
  • 车辆保险费用的申请模板
  • 其他综合收益科目有哪些
  • 简单描述php中的数组
  • 进项税额转出怎么做账务处理
  • day29--Java泛型02
  • 财务软件服务合同要交印花税吗
  • 其他应收款其他应付款的风险
  • 上月附加税计提多了怎么办
  • 如何减税降税
  • 私人帐户可以转账给对公账户吗
  • 补充医疗保险会查hiv吗
  • python捕获异常继续执行
  • 代收代缴水费可以加多少损耗
  • python字符串如何换行
  • sqlserver查询时报00bop错误
  • 出口退税款计入营业外收入
  • 增值税税率调整为13%从什么时候开始实行
  • 小规模纳税人个体户经营所得税怎么算
  • 税控服务费减免月底怎样结转
  • 物业电费加价如何处理
  • 已收款未开票未发货能确认收入吗
  • 被挂靠方并收取管理费的公司怎样处理账务?
  • 累计折旧的借贷方表示
  • 多计提的税费怎么处理
  • 营业收入包括主营业务收入
  • 代收代缴水电费协议
  • 公司基本账户如何开户
  • 股东股权转让印花税 公司承担
  • 固定资产清理期末
  • 什么叫建账
  • mysql数据库子查询
  • sql怎么比较两个表字段的内容
  • mysql数据库全量备份
  • win8怎么查看系统版本
  • 安装并激活navicat
  • 整理房间日记200
  • centos如何操作
  • win7系统登录QQ失败提示QQ软件已被破坏或部分文件已经丢失的解决方法
  • 驱动人生公司怎么样
  • myeclipse2013安装配置
  • awk fnr nr
  • meta 标签
  • 安卓开发viewpager的用法
  • js限制输入字符长度
  • JavaScript浏览器扩展
  • jquery中点击事件点击没动静
  • 泉州国税局网站首页
  • 工商注册app是不是在手机上可以完全操作
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设