JavaScript垃圾回收机制和内存泄漏

在C# java javascript等语言中,都有自己的垃圾回收机制。垃圾回收机制其实很简单,说白了就是找出不再用的变量,然后释放掉其所占的内存,以便更多进程能进入到内容。那么我们怎样才能知道哪些变量没有用了呢?一般我们采用2种垃圾回收算法。
-------标记-清除
--------引用计数

2012起所有现代浏览器的都才用了标记-清除垃圾回收算法,而较老版本的一些浏览器仍是采用引用计数的算法。
 

标记-清除

这是javascript最常用的垃圾回收算法。其原理就是,当变量进入到执行环境时,就标记其的状态为“进入环境”,当变量离开环境时,其就会清除之前的标记,再将该变量标为“离开环境”,最后,垃圾收集器就会完成内容释放并销毁带有‘离开环境’标记的变量。

但是,标记-清除有个问题就是,释放后的内存空间不是连续的,导致产生很多的内存碎片。这时标记-整理方法就会出场,将占用着内容的对象往一端移动,清除边界的内容,以整理出连续的内存空间。

 

引用计数

引用计算的原理是跟踪每个值被引用的总次数,每当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加 1,如果该变量的值变成了另外一个,则这个值得引用次数减 1,当这个值的引用次数变为 0 的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为 0 的值占用的内存。
但其有一个致命问题就是循环引用会引发内容泄漏

function problem() {
    var objA = new Object();
    var objB = new Object();
    objA.someObject = objB;
    objB.anotherObject = objA;
}

这个引用类型的一个值又指向了另一个引用类型,这样,每个引用类型的引用次数都是2,且在引用类型之间形成了循环引用,这样,即使problem()函数执行完毕,把后期不再使用的局部变量objA和objB释放,但是因为引用类型的引用次数还是1,那么这两个引用类型还是不能被释放的,这就造成了内存泄露。
解决方法:手动切断引用

objA = null;
objB = null;

 

内存泄漏

1.闭包

由于IE的js对象和DOM对象使用不同的垃圾收集方法,因此闭包在IE中会导致内存泄露问题,也就是无法销毁驻留在内存中的元素。
闭包可以维持函数内部变量驻留内存,使其得不到释放

function(){
 var oDiv = document.getElementById('oDiv');//oDiv用完之后一直驻留在内存中
    oDiv.onclick = function () {
        alert('oDiv.innerHTML');//这里用oDiv导致内存泄露
    };
  }

其无意间将变量oDiv泄漏到内存中,最简单的方法就是手动解除引用,或定义在函数外面。

oDiv = null;

 

2.全局变量

声明过多的全局变量,会导致变量常驻内存,要直到进程结束才能够释放内存。

 

3.无效的DOM引用

<div id="btn_container">
        <button id="btn">demo</button>
</div>
var g = function(id){return document.getElementById(id);}
        g('btn').onclick=function(){
            g('btn_container').innerHTML = "触发了事件!";
        }

这时点击btn时,就会触发事件处理把btn按钮给覆盖,但是其click事件没有被清除,就会泄露到内存中,当然可以将其设为null
g(‘btn’).οnclick=null;我们也可以使用更好的方法,事件委托来处理这类问题。

g('btn_container').onclick=function(e){
   //获取触发事件
   var target = e && e.target || window.event.srcElement;
   //判断触发事件元素id是否为btn
   if(target.id==='btn'){
      //重置父元素内容
      g('btn_container').innerHTML = '触发了事件';
   }
}

 

4.被遗忘的计时器或回调函数

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        // 处理 node 和 someResource
        node.innerHTML = JSON.stringify(someResource));
    }
}, 1000);

5.缓存

JS 开发者喜欢用对象的键值对来缓存函数的计算结果,但是缓存中存储的键越多,长期存活的对象也就越多,这将导致垃圾回收在进行扫描和整理时,对这些对象做无用功。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
系统根据B/S,即所谓的电脑浏览器/网络服务器方式,运用Java技术性,挑选MySQL作为后台系统。系统主要包含对客服聊天管理、字典表管理、公告信息管理、金融工具管理、金融工具收藏管理、金融工具银行卡管理、借款管理、理财产品管理、理财产品收藏管理、理财产品银行卡管理、理财银行卡信息管理、银行卡管理、存款管理、银行卡记录管理、取款管理、转账管理、用户管理、员工管理等功能模块。 文中重点介绍了银行管理的专业技术发展背景和发展状况,随后遵照软件传统式研发流程,最先挑选适用思维和语言软件开发平台,依据需求分析报告模块和设计数据库结构,再根据系统功能模块的设计制作系统功能模块图、流程表和E-R图。随后设计架构以及编写代码,并实现系统能模块。最终基本完成系统检测和功能测试。结果显示,该系统能够实现所需要的作用,工作状态没有明显缺陷。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。进入银行卡列表,管理员可以进行查看列表、模糊搜索以及相关维护等操作。用户进入系统可以查看公告和模糊搜索公告信息、也可以进行公告维护操作。理财产品管理页面,管理员可以进行查看列表、模糊搜索以及相关维护等操作。产品类型管理页面,此页面提供给管理员的功能有:新增产品类型,修改产品类型,删除产品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值